From e78bd5d010bd6ced2b71d83b88748f9cc8d98d5e Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 13 Oct 2017 21:42:49 +0200 Subject: Reorganize reader packages. --- src/cz/crcs/ectester/reader/test/TestSuite.java | 320 ++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 src/cz/crcs/ectester/reader/test/TestSuite.java (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java new file mode 100644 index 0000000..2f52f38 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -0,0 +1,320 @@ +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.DirtyLogger; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.ec.*; +import cz.crcs.ectester.reader.response.Response; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.*; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class TestSuite { + + EC_Store dataStore; + ECTester.Config cfg; + DirtyLogger systemOut; + String name; + List tests = new LinkedList<>(); + + TestSuite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut, String name) { + this.dataStore = dataStore; + this.cfg = cfg; + this.systemOut = systemOut; + this.name = name; + } + + public List run(CardMngr cardManager) throws CardException, IOException { + for (Test t : tests) { + if (!t.hasRun()) { + t.run(); + systemOut.println(t.toString()); + } + } + return tests; + } + + public List getTests() { + return Collections.unmodifiableList(tests); + } + + public String getName() { + return name; + } + + /** + * @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 ecdsaExpected expected result of the ordinary ECDSA command + * @return tests to run + */ + List testCurve(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List tests = new LinkedList<>(); + + tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); + + return tests; + } + + /** + * @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 ecdsaExpected expected result of the ordinary ECDSA command + * @return tests to run + */ + List testCategory(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + 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(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); + tests.addAll(testCurve(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + + return tests; + } + + public static class Default extends TestSuite { + + public Default(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "default"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + tests.add(new Test(new Command.Support(cardManager), Test.Result.ANY)); + if (cfg.namedCurve != null) { + if (cfg.primeField) { + tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + } + if (cfg.binaryField) { + tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + } + } 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); + } + } + } + return super.run(cardManager); + } + + private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); + Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); + if (curve != null) + tests.add(new Test(curve, Test.Result.SUCCESS)); + tests.addAll(testCurve(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + + public static class TestVectors extends TestSuite { + + public TestVectors(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "test"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + /* 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."); + } + + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + //tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + Response.ECDH dh = (Response.ECDH) response; + if (!dh.successful() || !dh.hasSecret()) + return Test.Result.FAILURE; + if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { + return Test.Result.FAILURE; + } + return Test.Result.SUCCESS; + })); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + + } + return super.run(cardManager); + } + } + + public static class Composite extends TestSuite { + + public Composite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "composite"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + /* 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(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); + tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + + //tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); + //tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); + + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + return super.run(cardManager); + } + } + + public static class Invalid extends TestSuite { + + public Invalid(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "invalid"); + } + + @Override + public List run(CardMngr cardManager) throws CardException, 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(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + for (EC_Key.Public pub : keys) { + // tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); + // tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); + } + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + + return super.run(cardManager); + } + } + + public static class Wrong extends TestSuite { + + public Wrong(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "wrong"); + } + + @Override + public List run(CardMngr cardManager) throws CardException, IOException { + /* Just do the default tests on the wrong curves. + * These should generally fail, the curves aren't curves. + */ + if (cfg.primeField) { + tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + } + if (cfg.binaryField) { + tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + } + return super.run(cardManager); + } + } +} -- cgit v1.3.1 From 88f829e238097343a044f437c2d4cfeb8b6cfdff Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 15 Oct 2017 00:01:42 +0200 Subject: Abstract out Test and move its simple implementation to Test.Simple. - Also create a Test.Compound nested static class that can combine multiple Tests and their Results, and has a single Result. --- src/cz/crcs/ectester/reader/test/Test.java | 175 +++++++++++++++++------- src/cz/crcs/ectester/reader/test/TestSuite.java | 72 +++++----- 2 files changed, 159 insertions(+), 88 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index e22e0a4..cd0cf49 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -5,35 +5,16 @@ import cz.crcs.ectester.reader.response.Response; import javax.smartcardio.CardException; import java.util.function.BiFunction; +import java.util.function.Function; /** + * An abstract test that can be run and has a Result. + * * @author Jan Jancar johny@neuromancer.sk */ -public class Test { - private boolean hasRun = false; - private BiFunction callback; - private Result result; - private Result expected; - private Command command; - private Response response; - - public Test(Command command, Result expected) { - this.command = command; - this.expected = expected; - } - - public Test(Command command, Result expected, BiFunction callback) { - this(command, expected); - this.callback = callback; - } - - public Command getCommand() { - return command; - } - - public Response getResponse() { - return response; - } +public abstract class Test { + boolean hasRun = false; + Result result; public Result getResult() { if (!hasRun) { @@ -42,44 +23,134 @@ public class Test { return result; } - public Result getExpected() { - return expected; + public boolean hasRun() { + return hasRun; } - public boolean ok() { - return result == expected || expected == Result.ANY; + public abstract boolean ok(); + + public abstract void run() throws CardException; + + /** + * A result of a Test. + */ + public enum Result { + SUCCESS, + FAILURE, + ANY } - public void run() throws CardException { - response = command.send(); - if (callback != null) { - result = callback.apply(command, response); - } else { - if (response.successful()) { - result = Result.SUCCESS; + /** + * A simple test that runs one Command to get and evaluate one Response + * to get a Result and compare it with the expected one. + */ + public static class Simple extends Test { + private BiFunction callback; + private Result expected; + private Command command; + private Response response; + + public Simple(Command command, Result expected) { + this.command = command; + this.expected = expected; + } + + public Simple(Command command, Result expected, BiFunction callback) { + this(command, expected); + this.callback = callback; + } + + public Command getCommand() { + return command; + } + + public Response getResponse() { + return response; + } + + public Result getExpected() { + return expected; + } + + @Override + public boolean ok() { + return result == expected || expected == Result.ANY; + } + + @Override + public void run() throws CardException { + response = command.send(); + if (callback != null) { + result = callback.apply(command, response); } else { - result = Result.FAILURE; + if (response.successful()) { + result = Result.SUCCESS; + } else { + result = Result.FAILURE; + } } + hasRun = true; } - hasRun = true; - } - public boolean hasRun() { - return hasRun; + @Override + public String toString() { + if (hasRun) { + return (ok() ? "OK " : "NOK") + " " + response.toString(); + } else { + return ""; + } + } } - @Override - public String toString() { - if (hasRun) { - return (ok() ? "OK " : "NOK") + " " + response.toString(); - } else { - return ""; + /** + * A compound test that runs many Tests and has a Result dependent on all/some of their Results. + */ + public static class Compound extends Test { + private Function callback; + private Test[] tests; + + private Compound(Function callback, Test... tests) { + this.callback = callback; + this.tests = tests; } - } - public enum Result { - SUCCESS, - FAILURE, - ANY + public Compound function(Function callback, Test... tests) { + return new Compound(callback, tests); + } + + public Compound all(Result what, Test... all) { + return new Compound((tests) -> { + for (Test test : tests) { + if (test.getResult() != what) { + return Result.FAILURE; + } + } + return Result.SUCCESS; + }, all); + } + + public Compound any(Result what, Test... any) { + return new Compound((tests) -> { + for (Test test : tests) { + if (test.getResult() == what) { + return Result.SUCCESS; + } + } + return Result.FAILURE; + }, any); + } + + @Override + public boolean ok() { + return result == Result.SUCCESS; + } + + @Override + public void run() throws CardException { + for (Test test: tests) { + test.run(); + } + result = callback.apply(tests); + } } } diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 2f52f38..7ce9e0f 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -62,14 +62,14 @@ public abstract class TestSuite { List testCurve(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { List tests = new LinkedList<>(); - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return tests; } @@ -92,10 +92,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 Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); tests.addAll(testCurve(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } @@ -110,7 +110,7 @@ public abstract class TestSuite { @Override public List run(CardMngr cardManager) throws IOException, CardException { - tests.add(new Test(new Command.Support(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); if (cfg.namedCurve != null) { if (cfg.primeField) { tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); @@ -146,12 +146,12 @@ public abstract class TestSuite { } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) - tests.add(new Test(curve, Test.Result.SUCCESS)); + tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); tests.addAll(testCurve(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } @@ -190,12 +190,12 @@ public abstract class TestSuite { throw new IOException("Test vector keys couldn't be located."); } - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - //tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { Response.ECDH dh = (Response.ECDH) response; if (!dh.successful() || !dh.hasSecret()) return Test.Result.FAILURE; @@ -204,7 +204,7 @@ public abstract class TestSuite { } return Test.Result.SUCCESS; })); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } return super.run(cardManager); @@ -235,15 +235,15 @@ public abstract class TestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); - //tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); - //tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); + //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); + //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } return super.run(cardManager); @@ -282,15 +282,15 @@ public abstract class TestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); for (EC_Key.Public pub : keys) { - // tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); - // tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); + // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); + // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); } - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } return super.run(cardManager); -- cgit v1.3.1 From 114c3378e323b954bfd8c0470e489c9615978d58 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 14 Oct 2017 01:14:07 +0200 Subject: Refactor response and test outputing into separate writers. This is done to provide multiple output formats, one which logs tests to console in simple human readable format and others. --- src/cz/crcs/ectester/reader/DirtyLogger.java | 56 -------------- src/cz/crcs/ectester/reader/ECTester.java | 83 ++++++++++++++------- .../ectester/reader/output/HTMLOutputWriter.java | 29 ++++++++ .../crcs/ectester/reader/output/OutputLogger.java | 60 +++++++++++++++ .../crcs/ectester/reader/output/OutputWriter.java | 14 ++++ .../ectester/reader/output/TeeOutputStream.java | 36 +++++++++ .../ectester/reader/output/TextOutputWriter.java | 72 ++++++++++++++++++ .../ectester/reader/output/XMLOutputWriter.java | 29 ++++++++ src/cz/crcs/ectester/reader/response/Response.java | 85 ++++++---------------- src/cz/crcs/ectester/reader/test/Test.java | 21 ++++-- src/cz/crcs/ectester/reader/test/TestSuite.java | 33 +++++---- 11 files changed, 352 insertions(+), 166 deletions(-) delete mode 100644 src/cz/crcs/ectester/reader/DirtyLogger.java create mode 100644 src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/OutputLogger.java create mode 100644 src/cz/crcs/ectester/reader/output/OutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/TeeOutputStream.java create mode 100644 src/cz/crcs/ectester/reader/output/TextOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/XMLOutputWriter.java (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/DirtyLogger.java b/src/cz/crcs/ectester/reader/DirtyLogger.java deleted file mode 100644 index 7a2c70d..0000000 --- a/src/cz/crcs/ectester/reader/DirtyLogger.java +++ /dev/null @@ -1,56 +0,0 @@ -package cz.crcs.ectester.reader; - -import java.io.FileWriter; -import java.io.IOException; -import java.io.OutputStream; - -/** - * @author Petr Svenda petr@svenda.com - * @author Jan Jancar johny@neuromancer.sk - */ -public class DirtyLogger { - FileWriter log; - boolean systemOut; - - public DirtyLogger(String filePath) throws IOException { - this(filePath, true); - } - - public DirtyLogger(String filePath, boolean systemOut) throws IOException { - if (filePath != null) - this.log = new FileWriter(filePath); - this.systemOut = systemOut; - } - - public void println() { - print("\n"); - } - - public void println(String logLine) { - logLine += "\n"; - print(logLine); - } - - public void print(String logLine) { - if (systemOut) { - System.out.print(logLine); - } - if (log != null) { - try { - log.write(logLine); - } catch (IOException ignored) { - } - } - } - - void flush() { - try { - if (log != null) log.flush(); - } catch (IOException ignored) { - } - } - - void close() throws IOException { - if (log != null) log.close(); - } -} diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index a43c945..c0c282c 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -22,13 +22,13 @@ package cz.crcs.ectester.reader; import cz.crcs.ectester.applet.ECTesterApplet; -import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Category; import cz.crcs.ectester.reader.ec.EC_Data; import cz.crcs.ectester.reader.ec.EC_Params; +import cz.crcs.ectester.reader.output.*; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.TestSuite; import javacard.security.KeyPair; @@ -39,6 +39,8 @@ import java.io.*; import java.nio.file.Files; import java.util.*; +import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + /** * Reader part of ECTester, a tool for testing Elliptic curve support on javacards. * @@ -48,7 +50,8 @@ import java.util.*; public class ECTester { private CardMngr cardManager; - private DirtyLogger systemOutLogger; + private OutputLogger logger; + private OutputWriter writer; private EC_Store dataStore; private Config cfg; @@ -101,7 +104,22 @@ public class ECTester { cardManager.send(SELECT_ECTESTERAPPLET); } - systemOutLogger = new DirtyLogger(cfg.log, true); + logger = new OutputLogger(true, cfg.log); + if (cfg.format == null) { + writer = new TextOutputWriter(logger.getPrintStream()); + } else { + switch (cfg.format) { + case "text": + writer = new TextOutputWriter(logger.getPrintStream()); + break; + case "xml": + writer = new XMLOutputWriter(); + break; + case "html": + writer = new HTMLOutputWriter(); + break; + } + } //do action if (cli.hasOption("export")) { @@ -118,7 +136,7 @@ public class ECTester { //disconnect cardManager.disconnectFromCard(); - systemOutLogger.close(); + logger.close(); } catch (MissingOptionException moex) { System.err.println("Missing required options, one of:"); @@ -157,11 +175,11 @@ public class ECTester { } catch (ParseException | IOException ex) { System.err.println(ex.getMessage()); } catch (CardException ex) { - if (systemOutLogger != null) - systemOutLogger.println(ex.getMessage()); + if (logger != null) + logger.println(ex.getMessage()); } finally { - if (systemOutLogger != null) - systemOutLogger.flush(); + if (logger != null) + logger.flush(); } } @@ -223,7 +241,7 @@ public class ECTester { actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do ECDH, [count] times.").hasArg().argName("count").optionalArg(true).build()); actions.addOption(Option.builder("dhc").longOpt("ecdhc").desc("Do ECDHC, [count] times.").hasArg().argName("count").optionalArg(true).build()); actions.addOption(Option.builder("dsa").longOpt("ecdsa").desc("Sign data with ECDSA, [count] times.").hasArg().argName("count").optionalArg(true).build()); - + opts.addOptionGroup(actions); OptionGroup size = new OptionGroup(); @@ -259,6 +277,7 @@ public class ECTester { opts.addOption(Option.builder("o").longOpt("output").desc("Output into file .").hasArg().argName("output_file").build()); opts.addOption(Option.builder("l").longOpt("log").desc("Log output into file [log_file].").hasArg().argName("log_file").optionalArg(true).build()); opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build()); + opts.addOption(Option.builder().longOpt("format").desc("Output format to use.").hasArg().argName("format").build()); opts.addOption(Option.builder("f").longOpt("fresh").desc("Generate fresh keys (set domain parameters before every generation).").build()); opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); @@ -328,7 +347,9 @@ public class ECTester { } sent.add(export); - systemOutLogger.println(Response.toString(sent)); + for (Response r : sent) { + writer.printResponse(r); + } EC_Params exported = new EC_Params(domain, export.getParams()); @@ -357,7 +378,7 @@ public class ECTester { while (generated < cfg.generateAmount || cfg.generateAmount == 0) { if ((cfg.fresh || generated == 0) && curve != null) { Response fresh = curve.send(); - systemOutLogger.println(fresh.toString()); + logger.println(fresh.toString()); } Command.Generate generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL); @@ -375,7 +396,7 @@ public class ECTester { break; } } - systemOutLogger.println(response.toString()); + logger.println(response.toString()); String pub = Util.bytesToHex(export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_W), false); String priv = Util.bytesToHex(export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S), false); @@ -385,7 +406,7 @@ public class ECTester { generated++; } Response cleanup = new Command.Cleanup(cardManager).send(); - systemOutLogger.println(cleanup.toString()); + logger.println(cleanup.toString()); keysFile.close(); } @@ -401,10 +422,10 @@ public class ECTester { switch (cfg.testSuite) { case "default": - suite = new TestSuite.Default(dataStore, cfg, systemOutLogger); + suite = new TestSuite.Default(dataStore, cfg, writer); break; case "test-vectors": - suite = new TestSuite.TestVectors(dataStore, cfg, systemOutLogger); + suite = new TestSuite.TestVectors(dataStore, cfg, writer); break; default: // These tests are dangerous, prompt before them. @@ -413,8 +434,8 @@ public class ECTester { if (!cfg.yes) { System.out.print("Do you want to proceed? (y/n): "); Scanner in = new Scanner(System.in); - String confirmation = in.nextLine(); - if (!Arrays.asList("yes", "YES", "y", "Y").contains(confirmation)) { + String confirmation = in.nextLine().toLowerCase(); + if (!Arrays.asList("yes","y").contains(confirmation)) { return; } in.close(); @@ -423,13 +444,13 @@ public class ECTester { switch (cfg.testSuite) { case "wrong": - suite = new TestSuite.Wrong(dataStore, cfg, systemOutLogger); + suite = new TestSuite.Wrong(dataStore, cfg, writer); break; case "composite": - suite = new TestSuite.Composite(dataStore, cfg, systemOutLogger); + suite = new TestSuite.Composite(dataStore, cfg, writer); break; case "invalid": - suite = new TestSuite.Invalid(dataStore, cfg, systemOutLogger); + suite = new TestSuite.Invalid(dataStore, cfg, writer); break; default: System.err.println("Unknown test suite."); @@ -455,7 +476,9 @@ public class ECTester { if (curve != null) prepare.add(curve.send()); - systemOutLogger.println(Response.toString(prepare)); + for (Response r : prepare) { + writer.printResponse(r); + } byte pubkey = (cfg.anyPublicKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; byte privkey = (cfg.anyPrivateKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; @@ -479,7 +502,9 @@ public class ECTester { Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send(); ecdh.add(perform); - systemOutLogger.println(Response.toString(ecdh)); + for (Response r : ecdh) { + writer.printResponse(r); + } if (!perform.successful() || !perform.hasSecret()) { if (retry < 10) { @@ -498,7 +523,7 @@ public class ECTester { ++done; } Response cleanup = new Command.Cleanup(cardManager).send(); - systemOutLogger.println(cleanup.toString()); + logger.println(cleanup.toString()); if (out != null) out.close(); @@ -536,7 +561,9 @@ public class ECTester { if (curve != null) prepare.add(curve.send()); - systemOutLogger.println(Response.toString(prepare)); + for (Response r : prepare) { + writer.printResponse(r); + } FileWriter out = null; if (cfg.output != null) { @@ -552,7 +579,9 @@ public class ECTester { Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, data).send(); ecdsa.add(perform); - systemOutLogger.println(Response.toString(ecdsa)); + for (Response r : ecdsa) { + writer.printResponse(r); + } if (!perform.successful() || !perform.hasSignature()) { if (retry < 10) { @@ -571,7 +600,7 @@ public class ECTester { ++done; } Response cleanup = new Command.Cleanup(cardManager).send(); - systemOutLogger.println(cleanup.toString()); + logger.println(cleanup.toString()); if (out != null) out.close(); @@ -617,6 +646,7 @@ public class ECTester { public boolean fresh = false; public boolean simulate = false; public boolean yes = false; + public String format; //Action-related options public String listNamed; @@ -666,6 +696,7 @@ public class ECTester { fresh = cli.hasOption("fresh"); simulate = cli.hasOption("simulate"); yes = cli.hasOption("yes"); + format = cli.getOptionValue("format"); if (cli.hasOption("list-named")) { listNamed = cli.getOptionValue("list-named"); diff --git a/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java new file mode 100644 index 0000000..c20771d --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java @@ -0,0 +1,29 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class HTMLOutputWriter implements OutputWriter { + @Override + public void begin() { + + } + + @Override + public void printResponse(Response r) { + + } + + @Override + public void printTest(Test t) { + + } + + @Override + public void end() { + + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/OutputLogger.java b/src/cz/crcs/ectester/reader/output/OutputLogger.java new file mode 100644 index 0000000..bf47a1f --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/OutputLogger.java @@ -0,0 +1,60 @@ +package cz.crcs.ectester.reader.output; + +import java.io.*; +import java.util.LinkedList; +import java.util.List; + +/** + * @author Petr Svenda petr@svenda.com + * @author Jan Jancar johny@neuromancer.sk + */ +public class OutputLogger { + private OutputStream out; + private PrintStream print; + + public OutputLogger(boolean systemOut, String... filePaths) throws IOException { + List streams = new LinkedList<>(); + for (String filePath : filePaths) { + if (filePath != null) { + streams.add(new FileOutputStream(filePath)); + } + } + if (systemOut) { + streams.add(System.out); + } + this.out = new TeeOutputStream(streams.toArray(new OutputStream[0])); + this.print = new PrintStream(this.out); + } + + public OutputLogger(String filePath) throws IOException { + this(true, filePath); + } + + public OutputStream getOutputStream() { + return this.out; + } + + public PrintStream getPrintStream() { + return this.print; + } + + public void println() { + print.println(); + } + + public void println(String logLine) { + print.println(logLine); + } + + public void print(String logLine) { + print.print(logLine); + } + + public void flush() { + print.flush(); + } + + public void close() { + print.close(); + } +} diff --git a/src/cz/crcs/ectester/reader/output/OutputWriter.java b/src/cz/crcs/ectester/reader/output/OutputWriter.java new file mode 100644 index 0000000..ddcef8c --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/OutputWriter.java @@ -0,0 +1,14 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public interface OutputWriter { + void begin(); + void printResponse(Response r); + void printTest(Test t); + void end(); +} diff --git a/src/cz/crcs/ectester/reader/output/TeeOutputStream.java b/src/cz/crcs/ectester/reader/output/TeeOutputStream.java new file mode 100644 index 0000000..e18d32b --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TeeOutputStream.java @@ -0,0 +1,36 @@ +package cz.crcs.ectester.reader.output; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TeeOutputStream extends OutputStream { + private OutputStream[] outputs; + + public TeeOutputStream(OutputStream... outputs) { + this.outputs = outputs; + } + + @Override + public void write(int b) throws IOException { + for (OutputStream out : outputs) { + out.write(b); + } + } + + @Override + public void flush() throws IOException { + for (OutputStream out :outputs) { + out.flush(); + } + } + + @Override + public void close() throws IOException { + for (OutputStream out :outputs) { + out.close(); + } + } +} diff --git a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java new file mode 100644 index 0000000..7e62e89 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java @@ -0,0 +1,72 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TextOutputWriter implements OutputWriter { + private PrintStream output; + + public TextOutputWriter(PrintStream output) { + this.output = output; + } + + @Override + public void begin() { + } + + private String testPrefix(Test t) { + return (t.ok() ? "OK" : "NOK"); + } + + private String responseSuffix(Response r) { + StringBuilder suffix = new StringBuilder(); + for (int j = 0; j < r.getNumSW(); ++j) { + short sw = r.getSW(j); + if (sw != 0) { + suffix.append(" ").append(Util.getSWString(sw)); + } + } + if (suffix.length() == 0) { + suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]"); + } + return String.format("%4d ms : %s", r.getDuration() / 1000000, suffix); + } + + @Override + public void printResponse(Response r) { + String out = ""; + out += String.format("%-62s:", r.getDescription()) + " : "; + out += responseSuffix(r); + output.println(out); + output.flush(); + } + + @Override + public void printTest(Test t) { + if (!t.hasRun()) + return; + + String out = ""; + if (t instanceof Test.Simple) { + Test.Simple test = (Test.Simple) t; + out += String.format("%-62s:", testPrefix(t) + " " + test.getDescription()) + " : "; + out += responseSuffix(test.getResponse()); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) t; + out += String.format("%-62s:", testPrefix(t) + " " + test.getDescription()); + } + + output.println(out); + output.flush(); + } + + @Override + public void end() { + } +} diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java new file mode 100644 index 0000000..2755501 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java @@ -0,0 +1,29 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class XMLOutputWriter implements OutputWriter { + @Override + public void begin() { + + } + + @Override + public void printResponse(Response r) { + + } + + @Override + public void printTest(Test t) { + + } + + @Override + public void end() { + + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 59b24fc..962261e 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -114,46 +114,7 @@ public abstract class Response { return this.success; } - @Override - public abstract String toString(); - - public String toString(String inner) { - StringBuilder suffix = new StringBuilder(); - for (int j = 0; j < getNumSW(); ++j) { - short sw = getSW(j); - if (sw != 0) { - suffix.append(" ").append(Util.getSWString(sw)); - } - } - if (suffix.length() == 0) { - suffix.append(" [").append(Util.getSW(getNaturalSW())).append("]"); - } - return String.format("%-62s:%4d ms : %s", inner, time / 1000000, suffix); - } - - public static String toString(List responses) { - return toString(responses, null); - } - - public static String toString(List responses, String prefix) { - if (prefix != null) - prefix += " | "; - StringBuilder out = new StringBuilder(); - for (int i = 0; i < responses.size(); ++i) { - Response r = responses.get(i); - - if (prefix != null) - out.append(prefix); - - String message = r.toString(); - out.append(message); - if (i < responses.size() - 1) { - out.append("\n"); - } - } - return out.toString(); - } - + public abstract String getDescription(); /** * @@ -168,8 +129,8 @@ public abstract class Response { } @Override - public String toString() { - return super.toString(String.format("Allocate KeyAgreement(%s) object", Util.getKATypeString(this.kaType))); + public String getDescription() { + return String.format("Allocated KeyAgreement(%s) object", Util.getKATypeString(this.kaType)); } } @@ -193,7 +154,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String field = keyClass == KeyPair.ALG_EC_FP ? "ALG_EC_FP" : "ALG_EC_F2M"; String key; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { @@ -201,7 +162,7 @@ public abstract class Response { } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Allocated %s %db %s", key, keyLength, field)); + return String.format("Allocated %s %db %s", key, keyLength, field); } } @@ -223,14 +184,14 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String key; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { key = "both keypairs"; } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Cleared %s", key)); + return String.format("Cleared %s", key); } } @@ -257,7 +218,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String name; switch (curve) { case EC_Consts.CURVE_default: @@ -287,7 +248,7 @@ public abstract class Response { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Set %s %s parameters on %s", name, what, pair)); + return String.format("Set %s %s parameters on %s", name, what, pair); } } @@ -317,7 +278,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String corrupt = Util.getCorruption(corruption); String pair; @@ -326,7 +287,7 @@ public abstract class Response { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Corrupted params of %s, %s", pair, corrupt)); + return String.format("Corrupted params of %s, %s", pair, corrupt); } } @@ -348,14 +309,14 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String key; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { key = "both keypairs"; } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Generated %s", key)); + return String.format("Generated %s", key); } } @@ -452,7 +413,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String source; if (key == EC_Consts.KEY_BOTH) { source = "both keys"; @@ -465,7 +426,7 @@ public abstract class Response { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Exported params from %s of %s", source, pair)); + return String.format("Exported params from %s of %s", source, pair); } } @@ -504,7 +465,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String algo = Util.getKA(type); String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; @@ -516,7 +477,7 @@ public abstract class Response { } else { validity = Util.getCorruption(corruption); } - return super.toString(String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity)); + return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity); } } @@ -547,10 +508,10 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String data = raw == null ? "random" : "provided"; - return super.toString(String.format("ECDSA with %s keypair(%s data)", key, data)); + return String.format("ECDSA with %s keypair(%s data)", key, data); } } @@ -566,8 +527,8 @@ public abstract class Response { } @Override - public String toString() { - return super.toString("Requested JCSystem object deletion"); + public String getDescription() { + return "Requested JCSystem object deletion"; } } @@ -584,8 +545,8 @@ public abstract class Response { } @Override - public String toString() { - return super.toString("Support of ECDH, ECDHC, ECDSA"); + public String getDescription() { + return "Support of ECDH, ECDHC, ECDSA"; } } } diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index cd0cf49..cb885e5 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -31,6 +31,8 @@ public abstract class Test { public abstract void run() throws CardException; + public abstract String getDescription(); + /** * A result of a Test. */ @@ -93,12 +95,8 @@ public abstract class Test { } @Override - public String toString() { - if (hasRun) { - return (ok() ? "OK " : "NOK") + " " + response.toString(); - } else { - return ""; - } + public String getDescription() { + return response.getDescription(); } } @@ -140,6 +138,10 @@ public abstract class Test { }, any); } + public Test[] getTests() { + return tests; + } + @Override public boolean ok() { return result == Result.SUCCESS; @@ -147,10 +149,15 @@ public abstract class Test { @Override public void run() throws CardException { - for (Test test: tests) { + for (Test test : tests) { test.run(); } result = callback.apply(tests); } + + @Override + public String getDescription() { + return ""; + } } } diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 7ce9e0f..33c462f 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -4,11 +4,12 @@ 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.DirtyLogger; +import cz.crcs.ectester.reader.output.OutputLogger; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.*; +import cz.crcs.ectester.reader.output.OutputWriter; import cz.crcs.ectester.reader.response.Response; import javacard.security.KeyPair; @@ -23,24 +24,26 @@ public abstract class TestSuite { EC_Store dataStore; ECTester.Config cfg; - DirtyLogger systemOut; + OutputWriter writer; String name; List tests = new LinkedList<>(); - TestSuite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut, String name) { + TestSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer, String name) { this.dataStore = dataStore; this.cfg = cfg; - this.systemOut = systemOut; + this.writer = writer; this.name = name; } public List run(CardMngr cardManager) throws CardException, IOException { + writer.begin(); for (Test t : tests) { if (!t.hasRun()) { t.run(); - systemOut.println(t.toString()); + writer.printTest(t); } } + writer.end(); return tests; } @@ -104,8 +107,8 @@ public abstract class TestSuite { public static class Default extends TestSuite { - public Default(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "default"); + public Default(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "default"); } @Override @@ -157,8 +160,8 @@ public abstract class TestSuite { public static class TestVectors extends TestSuite { - public TestVectors(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "test"); + public TestVectors(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "test"); } @Override @@ -213,8 +216,8 @@ public abstract class TestSuite { public static class Composite extends TestSuite { - public Composite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "composite"); + public Composite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "composite"); } @Override @@ -252,8 +255,8 @@ public abstract class TestSuite { public static class Invalid extends TestSuite { - public Invalid(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "invalid"); + public Invalid(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "invalid"); } @Override @@ -299,8 +302,8 @@ public abstract class TestSuite { public static class Wrong extends TestSuite { - public Wrong(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "wrong"); + public Wrong(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "wrong"); } @Override -- cgit v1.3.1 From 697482644f1d264bff8ffca8a5ac5d71058a4654 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 24 Oct 2017 19:03:06 +0200 Subject: Rename some OutputWriter methods, add YAMLOutputWriter. --- src/cz/crcs/ectester/reader/ECTester.java | 10 ++++---- .../ectester/reader/output/HTMLOutputWriter.java | 29 ---------------------- .../crcs/ectester/reader/output/OutputWriter.java | 4 +-- .../ectester/reader/output/TextOutputWriter.java | 4 +-- .../ectester/reader/output/XMLOutputWriter.java | 4 +-- .../ectester/reader/output/YAMLOutputWriter.java | 29 ++++++++++++++++++++++ src/cz/crcs/ectester/reader/test/TestSuite.java | 19 +++++++------- 7 files changed, 49 insertions(+), 50 deletions(-) delete mode 100644 src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 0d558cb..1b69998 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -351,7 +351,7 @@ public class ECTester { sent.add(export); for (Response r : sent) { - writer.printResponse(r); + writer.outputResponse(r); } EC_Params exported = new EC_Params(domain, export.getParams()); @@ -480,7 +480,7 @@ public class ECTester { prepare.add(curve.send()); for (Response r : prepare) { - writer.printResponse(r); + writer.outputResponse(r); } byte pubkey = (cfg.anyPublicKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; @@ -506,7 +506,7 @@ public class ECTester { Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send(); ecdh.add(perform); for (Response r : ecdh) { - writer.printResponse(r); + writer.outputResponse(r); } if (!perform.successful() || !perform.hasSecret()) { @@ -565,7 +565,7 @@ public class ECTester { prepare.add(curve.send()); for (Response r : prepare) { - writer.printResponse(r); + writer.outputResponse(r); } FileWriter out = null; @@ -583,7 +583,7 @@ public class ECTester { Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, data).send(); ecdsa.add(perform); for (Response r : ecdsa) { - writer.printResponse(r); + writer.outputResponse(r); } if (!perform.successful() || !perform.hasSignature()) { diff --git a/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java deleted file mode 100644 index c20771d..0000000 --- a/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java +++ /dev/null @@ -1,29 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class HTMLOutputWriter implements OutputWriter { - @Override - public void begin() { - - } - - @Override - public void printResponse(Response r) { - - } - - @Override - public void printTest(Test t) { - - } - - @Override - public void end() { - - } -} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/OutputWriter.java b/src/cz/crcs/ectester/reader/output/OutputWriter.java index 761d712..09185b1 100644 --- a/src/cz/crcs/ectester/reader/output/OutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/OutputWriter.java @@ -12,7 +12,7 @@ import javax.xml.transform.TransformerException; */ public interface OutputWriter { void begin(); - void printResponse(Response r); - void printTest(Test t); + void outputResponse(Response r); + void outputTest(Test t); void end(); } diff --git a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java index 7e62e89..6887f61 100644 --- a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java @@ -39,7 +39,7 @@ public class TextOutputWriter implements OutputWriter { } @Override - public void printResponse(Response r) { + public void outputResponse(Response r) { String out = ""; out += String.format("%-62s:", r.getDescription()) + " : "; out += responseSuffix(r); @@ -48,7 +48,7 @@ public class TextOutputWriter implements OutputWriter { } @Override - public void printTest(Test t) { + public void outputTest(Test t) { if (!t.hasRun()) return; diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java index 4f72a16..b9f8c8f 100644 --- a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java @@ -65,7 +65,7 @@ public class XMLOutputWriter implements OutputWriter { } @Override - public void printResponse(Response r) { + public void outputResponse(Response r) { root.appendChild(responseElement(r)); } @@ -96,7 +96,7 @@ public class XMLOutputWriter implements OutputWriter { } @Override - public void printTest(Test t) { + public void outputTest(Test t) { if (!t.hasRun()) return; root.appendChild(testElement(t)); diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java new file mode 100644 index 0000000..34ff29a --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java @@ -0,0 +1,29 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class YAMLOutputWriter implements OutputWriter { + @Override + public void begin() { + + } + + @Override + public void outputResponse(Response r) { + + } + + @Override + public void outputTest(Test t) { + + } + + @Override + public void end() { + + } +} diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 33c462f..8369439 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -4,7 +4,6 @@ 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.output.OutputLogger; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.command.Command; @@ -40,7 +39,7 @@ public abstract class TestSuite { for (Test t : tests) { if (!t.hasRun()) { t.run(); - writer.printTest(t); + writer.outputTest(t); } } writer.end(); @@ -62,7 +61,7 @@ public abstract class TestSuite { * @param ecdsaExpected expected result of the ordinary ECDSA command * @return tests to run */ - List testCurve(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List defaultCurveTests(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { List tests = new LinkedList<>(); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); @@ -87,7 +86,7 @@ public abstract class TestSuite { * @param ecdsaExpected expected result of the ordinary ECDSA command * @return tests to run */ - List testCategory(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List defaultCategoryTests(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { List tests = new LinkedList<>(); Map curves = dataStore.getObjects(EC_Curve.class, category); if (curves == null) @@ -97,7 +96,7 @@ public abstract class TestSuite { if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); - tests.addAll(testCurve(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); + tests.addAll(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } @@ -116,10 +115,10 @@ public abstract class TestSuite { tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); if (cfg.namedCurve != null) { if (cfg.primeField) { - tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); } if (cfg.binaryField) { - tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); } } else { if (cfg.all) { @@ -153,7 +152,7 @@ public abstract class TestSuite { Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); - tests.addAll(testCurve(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCurveTests(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } @@ -312,10 +311,10 @@ public abstract class TestSuite { * These should generally fail, the curves aren't curves. */ if (cfg.primeField) { - tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); } if (cfg.binaryField) { - tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); } return super.run(cardManager); } -- cgit v1.3.1 From ffbbf6e6482d48f4d49dd2ba1a63f687978415f8 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 00:10:56 +0200 Subject: Add Compund test to test-vectors suite. --- .../ectester/reader/output/TextOutputWriter.java | 24 ++++++++----- .../ectester/reader/output/YAMLOutputWriter.java | 6 +++- src/cz/crcs/ectester/reader/test/Test.java | 39 ++++++++++++++++++++++ src/cz/crcs/ectester/reader/test/TestSuite.java | 29 +++++++++++++--- 4 files changed, 83 insertions(+), 15 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java index 6887f61..d9669be 100644 --- a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java @@ -47,22 +47,28 @@ public class TextOutputWriter implements OutputWriter { output.flush(); } - @Override - public void outputTest(Test t) { + private String testString(Test t) { if (!t.hasRun()) - return; + return null; - String out = ""; + StringBuilder out = new StringBuilder(); if (t instanceof Test.Simple) { Test.Simple test = (Test.Simple) t; - out += String.format("%-62s:", testPrefix(t) + " " + test.getDescription()) + " : "; - out += responseSuffix(test.getResponse()); - } else if (t instanceof Test.Compound) { + out.append(String.format("%-62s:", testPrefix(t) + " " + test.getDescription())).append(" : "); + out.append(responseSuffix(test.getResponse())); + } else if (t instanceof Test.Compound) { Test.Compound test = (Test.Compound) t; - out += String.format("%-62s:", testPrefix(t) + " " + test.getDescription()); + for (Test innerTest : test.getTests()) { + out.append(" ").append(testString(innerTest)).append(System.lineSeparator()); + } + out.append(String.format("%-62s:", testPrefix(t) + " " + test.getDescription())); } + return out.toString(); + } - output.println(out); + @Override + public void outputTest(Test t) { + output.println(testString(t)); output.flush(); } diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java index e81cbad..211bd47 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java @@ -82,7 +82,11 @@ public class YAMLOutputWriter implements OutputWriter { DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); Yaml yaml = new Yaml(options); - String out = yaml.dump(testRun); + + 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/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 14cf554..f873c19 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -114,10 +114,19 @@ public abstract class Test { this.tests = tests; } + private Compound(Function callback, String descripiton, Test... tests) { + this(callback, tests); + this.description = descripiton; + } + public static Compound function(Function callback, Test... tests) { return new Compound(callback, tests); } + public static Compound function(Function callback, String description, Test... tests) { + return new Compound(callback, description, tests); + } + public static Compound all(Result what, Test... all) { return new Compound((tests) -> { for (Test test : tests) { @@ -129,6 +138,12 @@ public abstract class Test { }, all); } + public static Compound all(Result what, String description, Test... all) { + Compound result = Compound.all(what, all); + result.setDescription(description); + return result; + } + public static Compound any(Result what, Test... any) { return new Compound((tests) -> { for (Test test : tests) { @@ -140,6 +155,29 @@ public abstract class Test { }, any); } + public static Compound any(Result what, String description, Test... any) { + Compound result = Compound.any(what, any); + result.setDescription(description); + return result; + } + + public static Compound mask(Result[] results, Test... masked) { + return new Compound((tests) -> { + for (int i = 0; i < results.length; ++i) { + if (results[i] != Result.ANY && results[i] != tests[i].getResult()) { + return Result.FAILURE; + } + } + return Result.SUCCESS; + }, masked); + } + + public static Compound mask(Result[] results, String description, Test... masked) { + Compound result = Compound.mask(results, masked); + result.setDescription(description); + return result; + } + public Test[] getTests() { return tests; } @@ -155,6 +193,7 @@ public abstract class Test { test.run(); } result = callback.apply(tests); + this.hasRun = true; } public void setDescription(String description) { diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 8369439..4bca641 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.reader.test; +import static cz.crcs.ectester.reader.test.Test.Result; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; @@ -104,6 +105,9 @@ public abstract class TestSuite { return tests; } + /** + * + */ public static class Default extends TestSuite { public Default(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { @@ -157,6 +161,9 @@ public abstract class TestSuite { } } + /** + * + */ public static class TestVectors extends TestSuite { public TestVectors(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { @@ -191,13 +198,14 @@ public abstract class TestSuite { if (onekey == null || otherkey == null) { throw new IOException("Test vector keys couldn't be located."); } + List testVector = new LinkedList<>(); - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { Response.ECDH dh = (Response.ECDH) response; if (!dh.successful() || !dh.hasSecret()) return Test.Result.FAILURE; @@ -206,6 +214,8 @@ public abstract class TestSuite { } return Test.Result.SUCCESS; })); + //tests.addAll(testVector); + tests.add(Test.Compound.all(Result.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } @@ -213,6 +223,9 @@ public abstract class TestSuite { } } + /** + * + */ public static class Composite extends TestSuite { public Composite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { @@ -252,6 +265,9 @@ public abstract class TestSuite { } } + /** + * + */ public static class Invalid extends TestSuite { public Invalid(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { @@ -299,6 +315,9 @@ public abstract class TestSuite { } } + /** + * + */ public static class Wrong extends TestSuite { public Wrong(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { -- cgit v1.3.1 From 3f37a993d1e2d9a2f547d34774ddca2a55804223 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 00:42:57 +0200 Subject: Split TestSuite classes into separate files. --- src/cz/crcs/ectester/reader/ECTester.java | 12 +- .../ectester/reader/test/CompositeCurvesSuite.java | 60 ++++++ src/cz/crcs/ectester/reader/test/DefaultSuite.java | 71 +++++++ .../ectester/reader/test/InvalidCurvesSuite.java | 70 ++++++ src/cz/crcs/ectester/reader/test/TestSuite.java | 234 --------------------- .../crcs/ectester/reader/test/TestVectorSuite.java | 81 +++++++ .../ectester/reader/test/WrongCurvesSuite.java | 36 ++++ 7 files changed, 324 insertions(+), 240 deletions(-) create mode 100644 src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/DefaultSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/TestVectorSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 1d12d00..5a2274d 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -30,7 +30,7 @@ import cz.crcs.ectester.reader.ec.EC_Data; import cz.crcs.ectester.reader.ec.EC_Params; import cz.crcs.ectester.reader.output.*; import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.TestSuite; +import cz.crcs.ectester.reader.test.*; import javacard.security.KeyPair; import org.apache.commons.cli.*; @@ -425,10 +425,10 @@ public class ECTester { switch (cfg.testSuite) { case "default": - suite = new TestSuite.Default(dataStore, cfg, writer); + suite = new DefaultSuite(dataStore, cfg, writer); break; case "test-vectors": - suite = new TestSuite.TestVectors(dataStore, cfg, writer); + suite = new TestVectorSuite(dataStore, cfg, writer); break; default: // These tests are dangerous, prompt before them. @@ -447,13 +447,13 @@ public class ECTester { switch (cfg.testSuite) { case "wrong": - suite = new TestSuite.Wrong(dataStore, cfg, writer); + suite = new WrongCurvesSuite(dataStore, cfg, writer); break; case "composite": - suite = new TestSuite.Composite(dataStore, cfg, writer); + suite = new CompositeCurvesSuite(dataStore, cfg, writer); break; case "invalid": - suite = new TestSuite.Invalid(dataStore, cfg, writer); + suite = new InvalidCurvesSuite(dataStore, cfg, writer); break; default: System.err.println("Unknown test suite."); diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java new file mode 100644 index 0000000..75c6371 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -0,0 +1,60 @@ +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.ECTester; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.ec.EC_Curve; +import cz.crcs.ectester.reader.ec.EC_Key; +import cz.crcs.ectester.reader.output.OutputWriter; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class CompositeCurvesSuite extends TestSuite { + + public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "composite"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + /* 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(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + + //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); + //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); + + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + return super.run(cardManager); + } +} diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java new file mode 100644 index 0000000..2024578 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -0,0 +1,71 @@ +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.ECTester; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.output.OutputWriter; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.List; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class DefaultSuite extends TestSuite { + + public DefaultSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "default"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); + if (cfg.namedCurve != null) { + if (cfg.primeField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + } + if (cfg.binaryField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + } + } 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); + } + } + } + return super.run(cardManager); + } + + private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); + Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); + if (curve != null) + tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); + tests.addAll(defaultCurveTests(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + } +} diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java new file mode 100644 index 0000000..20882b6 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.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.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.ec.EC_Curve; +import cz.crcs.ectester.reader.ec.EC_Key; +import cz.crcs.ectester.reader.output.OutputWriter; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class InvalidCurvesSuite extends TestSuite { + + public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "invalid"); + } + + @Override + public List run(CardMngr cardManager) throws CardException, 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(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + for (EC_Key.Public pub : keys) { + // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); + // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); + } + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + + return super.run(cardManager); + } +} diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 4bca641..fde2266 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -104,238 +104,4 @@ public abstract class TestSuite { return tests; } - - /** - * - */ - public static class Default extends TestSuite { - - public Default(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "default"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); - if (cfg.namedCurve != null) { - if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - } - if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - } - } 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); - } - } - } - return super.run(cardManager); - } - - private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); - if (curve != null) - tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); - tests.addAll(defaultCurveTests(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - } - - /** - * - */ - public static class TestVectors extends TestSuite { - - public TestVectors(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "test"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - /* 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(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { - Response.ECDH dh = (Response.ECDH) response; - if (!dh.successful() || !dh.hasSecret()) - return Test.Result.FAILURE; - if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { - return Test.Result.FAILURE; - } - return Test.Result.SUCCESS; - })); - //tests.addAll(testVector); - tests.add(Test.Compound.all(Result.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); - - } - return super.run(cardManager); - } - } - - /** - * - */ - public static class Composite extends TestSuite { - - public Composite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "composite"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - /* 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(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); - - //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); - //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); - - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - } - return super.run(cardManager); - } - } - - /** - * - */ - public static class Invalid extends TestSuite { - - public Invalid(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "invalid"); - } - - @Override - public List run(CardMngr cardManager) throws CardException, 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(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); - for (EC_Key.Public pub : keys) { - // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); - // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); - } - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - - return super.run(cardManager); - } - } - - /** - * - */ - public static class Wrong extends TestSuite { - - public Wrong(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "wrong"); - } - - @Override - public List run(CardMngr cardManager) throws CardException, IOException { - /* Just do the default tests on the wrong curves. - * These should generally fail, the curves aren't curves. - */ - if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); - } - if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); - } - return super.run(cardManager); - } - } } diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java new file mode 100644 index 0000000..69f4ca3 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -0,0 +1,81 @@ +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.ECTester; +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.ec.*; +import cz.crcs.ectester.reader.output.OutputWriter; +import cz.crcs.ectester.reader.response.Response; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class TestVectorSuite extends TestSuite { + + public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "test"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + /* 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(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + Response.ECDH dh = (Response.ECDH) response; + if (!dh.successful() || !dh.hasSecret()) + return Test.Result.FAILURE; + if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { + return Test.Result.FAILURE; + } + return Test.Result.SUCCESS; + })); + tests.add(Test.Compound.all(Test.Result.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + + } + return super.run(cardManager); + } +} diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java new file mode 100644 index 0000000..3346b9f --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -0,0 +1,36 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.output.OutputWriter; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.List; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class WrongCurvesSuite extends TestSuite { + + public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "wrong"); + } + + @Override + public List run(CardMngr cardManager) throws CardException, IOException { + /* Just do the default tests on the wrong curves. + * These should generally fail, the curves aren't curves. + */ + if (cfg.primeField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + } + if (cfg.binaryField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + } + return super.run(cardManager); + } +} -- cgit v1.3.1 From 2c6c2a2d35292368b7263fedb6db508da7ded4c4 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 20:17:07 +0200 Subject: Split ResponseWriter into separate class, introduce TestRunner. --- src/cz/crcs/ectester/reader/ECTester.java | 43 ++++---- .../crcs/ectester/reader/output/OutputWriter.java | 18 ---- .../ectester/reader/output/ResponseWriter.java | 39 +++++++ .../ectester/reader/output/TeeOutputStream.java | 4 +- src/cz/crcs/ectester/reader/output/TestWriter.java | 15 +++ .../ectester/reader/output/TextOutputWriter.java | 86 --------------- .../ectester/reader/output/TextTestWriter.java | 66 ++++++++++++ .../ectester/reader/output/XMLOutputWriter.java | 118 --------------------- .../crcs/ectester/reader/output/XMLTestWriter.java | 117 ++++++++++++++++++++ .../ectester/reader/output/YAMLOutputWriter.java | 93 ---------------- .../ectester/reader/output/YAMLTestWriter.java | 92 ++++++++++++++++ .../ectester/reader/test/CompositeCurvesSuite.java | 9 +- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 11 +- .../ectester/reader/test/InvalidCurvesSuite.java | 11 +- src/cz/crcs/ectester/reader/test/TestRunner.java | 29 +++++ src/cz/crcs/ectester/reader/test/TestSuite.java | 22 +--- .../crcs/ectester/reader/test/TestVectorSuite.java | 10 +- .../ectester/reader/test/WrongCurvesSuite.java | 9 +- 18 files changed, 405 insertions(+), 387 deletions(-) delete mode 100644 src/cz/crcs/ectester/reader/output/OutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/ResponseWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/TestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/TextOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/TextTestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/XMLOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/XMLTestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/YAMLTestWriter.java create mode 100644 src/cz/crcs/ectester/reader/test/TestRunner.java (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 5a2274d..271a8e4 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -52,7 +52,8 @@ public class ECTester { private CardMngr cardManager; private OutputLogger logger; - private OutputWriter writer; + private TestWriter testWriter; + private ResponseWriter respWriter; private EC_Store dataStore; private Config cfg; @@ -105,22 +106,25 @@ public class ECTester { cardManager.send(SELECT_ECTESTERAPPLET); } + // Setup logger, testWriter and respWriter logger = new OutputLogger(true, cfg.log); if (cfg.format == null) { - writer = new TextOutputWriter(logger.getPrintStream()); + testWriter = new TextTestWriter(logger.getPrintStream()); } else { switch (cfg.format) { case "text": - writer = new TextOutputWriter(logger.getPrintStream()); + testWriter = new TextTestWriter(logger.getPrintStream()); break; case "xml": - writer = new XMLOutputWriter(logger.getOutputStream()); + testWriter = new XMLTestWriter(logger.getOutputStream()); break; case "yaml": - writer = new YAMLOutputWriter(logger.getPrintStream()); + case "yml": + testWriter = new YAMLTestWriter(logger.getPrintStream()); break; } } + respWriter = new ResponseWriter(logger.getPrintStream()); //do action if (cli.hasOption("export")) { @@ -351,7 +355,7 @@ public class ECTester { sent.add(export); for (Response r : sent) { - writer.outputResponse(r); + respWriter.outputResponse(r); } EC_Params exported = new EC_Params(domain, export.getParams()); @@ -425,10 +429,10 @@ public class ECTester { switch (cfg.testSuite) { case "default": - suite = new DefaultSuite(dataStore, cfg, writer); + suite = new DefaultSuite(dataStore, cfg); break; case "test-vectors": - suite = new TestVectorSuite(dataStore, cfg, writer); + suite = new TestVectorSuite(dataStore, cfg); break; default: // These tests are dangerous, prompt before them. @@ -438,7 +442,7 @@ public class ECTester { System.out.print("Do you want to proceed? (y/n): "); Scanner in = new Scanner(System.in); String confirmation = in.nextLine().toLowerCase(); - if (!Arrays.asList("yes","y").contains(confirmation)) { + if (!Arrays.asList("yes", "y").contains(confirmation)) { return; } in.close(); @@ -447,13 +451,13 @@ public class ECTester { switch (cfg.testSuite) { case "wrong": - suite = new WrongCurvesSuite(dataStore, cfg, writer); + suite = new WrongCurvesSuite(dataStore, cfg); break; case "composite": - suite = new CompositeCurvesSuite(dataStore, cfg, writer); + suite = new CompositeCurvesSuite(dataStore, cfg); break; case "invalid": - suite = new InvalidCurvesSuite(dataStore, cfg, writer); + suite = new InvalidCurvesSuite(dataStore, cfg); break; default: System.err.println("Unknown test suite."); @@ -461,7 +465,10 @@ public class ECTester { } break; } - suite.run(cardManager); + + TestRunner runner = new TestRunner(suite, testWriter); + suite.setup(cardManager); + runner.run(); } /** @@ -480,7 +487,7 @@ public class ECTester { prepare.add(curve.send()); for (Response r : prepare) { - writer.outputResponse(r); + respWriter.outputResponse(r); } byte pubkey = (cfg.anyPublicKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; @@ -506,7 +513,7 @@ public class ECTester { Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send(); ecdh.add(perform); for (Response r : ecdh) { - writer.outputResponse(r); + respWriter.outputResponse(r); } if (!perform.successful() || !perform.hasSecret()) { @@ -565,7 +572,7 @@ public class ECTester { prepare.add(curve.send()); for (Response r : prepare) { - writer.outputResponse(r); + respWriter.outputResponse(r); } FileWriter out = null; @@ -583,7 +590,7 @@ public class ECTester { Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, data).send(); ecdsa.add(perform); for (Response r : ecdsa) { - writer.outputResponse(r); + respWriter.outputResponse(r); } if (!perform.successful() || !perform.hasSignature()) { @@ -706,7 +713,7 @@ public class ECTester { } format = cli.getOptionValue("format", "text"); - if (!Arrays.asList("text", "xml", "yaml").contains(format)) { + if (!Arrays.asList("text", "xml", "yaml", "yml").contains(format)) { System.err.println("Wrong output format " + format + "."); return false; } diff --git a/src/cz/crcs/ectester/reader/output/OutputWriter.java b/src/cz/crcs/ectester/reader/output/OutputWriter.java deleted file mode 100644 index 09185b1..0000000 --- a/src/cz/crcs/ectester/reader/output/OutputWriter.java +++ /dev/null @@ -1,18 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; - -import javax.xml.stream.XMLStreamException; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public interface OutputWriter { - void begin(); - void outputResponse(Response r); - void outputTest(Test t); - void end(); -} diff --git a/src/cz/crcs/ectester/reader/output/ResponseWriter.java b/src/cz/crcs/ectester/reader/output/ResponseWriter.java new file mode 100644 index 0000000..120fdba --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/ResponseWriter.java @@ -0,0 +1,39 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.response.Response; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class ResponseWriter { + private PrintStream output; + + public ResponseWriter(PrintStream output) { + this.output = output; + } + + public String responseSuffix(Response r) { + StringBuilder suffix = new StringBuilder(); + for (int j = 0; j < r.getNumSW(); ++j) { + short sw = r.getSW(j); + if (sw != 0) { + suffix.append(" ").append(Util.getSWString(sw)); + } + } + if (suffix.length() == 0) { + suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]"); + } + return String.format("%4d ms : %s", r.getDuration() / 1000000, suffix); + } + + public void outputResponse(Response r) { + String out = ""; + out += String.format("%-70s:", r.getDescription()) + " : "; + out += responseSuffix(r); + output.println(out); + output.flush(); + } +} diff --git a/src/cz/crcs/ectester/reader/output/TeeOutputStream.java b/src/cz/crcs/ectester/reader/output/TeeOutputStream.java index e18d32b..2a1af99 100644 --- a/src/cz/crcs/ectester/reader/output/TeeOutputStream.java +++ b/src/cz/crcs/ectester/reader/output/TeeOutputStream.java @@ -22,14 +22,14 @@ public class TeeOutputStream extends OutputStream { @Override public void flush() throws IOException { - for (OutputStream out :outputs) { + for (OutputStream out : outputs) { out.flush(); } } @Override public void close() throws IOException { - for (OutputStream out :outputs) { + for (OutputStream out : outputs) { out.close(); } } diff --git a/src/cz/crcs/ectester/reader/output/TestWriter.java b/src/cz/crcs/ectester/reader/output/TestWriter.java new file mode 100644 index 0000000..74c76fb --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TestWriter.java @@ -0,0 +1,15 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.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/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java deleted file mode 100644 index 7f9cdae..0000000 --- a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java +++ /dev/null @@ -1,86 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.Util; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; - -import java.io.PrintStream; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TextOutputWriter implements OutputWriter { - private PrintStream output; - - public TextOutputWriter(PrintStream output) { - this.output = output; - } - - @Override - public void begin() { - } - - private String testPrefix(Test t) { - return String.format("%-4s", t.getResult() == Test.Result.SUCCESS ? "OK" : "NOK"); - } - - private String responseSuffix(Response r) { - StringBuilder suffix = new StringBuilder(); - for (int j = 0; j < r.getNumSW(); ++j) { - short sw = r.getSW(j); - if (sw != 0) { - suffix.append(" ").append(Util.getSWString(sw)); - } - } - if (suffix.length() == 0) { - suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]"); - } - return String.format("%4d ms : %s", r.getDuration() / 1000000, suffix); - } - - @Override - public void outputResponse(Response r) { - String out = ""; - out += String.format("%-70s:", r.getDescription()) + " : "; - out += responseSuffix(r); - output.println(out); - output.flush(); - } - - private String testString(Test t) { - if (!t.hasRun()) - return null; - - StringBuilder out = new StringBuilder(); - if (t instanceof Test.Simple) { - Test.Simple test = (Test.Simple) t; - out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())).append(" : "); - out.append(responseSuffix(test.getResponse())); - } else if (t instanceof Test.Compound) { - Test.Compound test = (Test.Compound) t; - Test[] tests = test.getTests(); - for (int i = 0; i < tests.length; ++i) { - if (i == 0) { - out.append(" /- "); - } else if (i == tests.length - 1) { - out.append(" \\- "); - } else { - out.append(" | "); - } - out.append(testString(tests[i])).append(System.lineSeparator()); - } - out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())); - } - return out.toString(); - } - - @Override - public void outputTest(Test t) { - output.println(testString(t)); - output.flush(); - } - - @Override - public void end() { - } -} 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..80c7204 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -0,0 +1,66 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.TestSuite; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TextTestWriter implements TestWriter { + private PrintStream output; + private ResponseWriter respWriter; + + public TextTestWriter(PrintStream output) { + this.output = output; + this.respWriter = new ResponseWriter(output); + } + + @Override + public void begin(TestSuite suite) { + } + + private String testPrefix(Test t) { + return String.format("%-4s", t.getResult() == Test.Result.SUCCESS ? "OK" : "NOK"); + } + + private String testString(Test t) { + if (!t.hasRun()) + return null; + + StringBuilder out = new StringBuilder(); + if (t instanceof Test.Simple) { + Test.Simple test = (Test.Simple) t; + out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())).append(" : "); + out.append(respWriter.responseSuffix(test.getResponse())); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) t; + Test[] tests = test.getTests(); + for (int i = 0; i < tests.length; ++i) { + if (i == 0) { + out.append(" /- "); + } else if (i == tests.length - 1) { + out.append(" \\- "); + } else { + out.append(" | "); + } + out.append(testString(tests[i])).append(System.lineSeparator()); + } + out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())); + } + return out.toString(); + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + output.println(testString(t)); + output.flush(); + } + + @Override + public void end() { + } +} diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java deleted file mode 100644 index b9f8c8f..0000000 --- a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java +++ /dev/null @@ -1,118 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.Util; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.*; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import java.io.OutputStream; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class XMLOutputWriter implements OutputWriter { - private OutputStream output; - private Document doc; - private Node root; - - public XMLOutputWriter(OutputStream output) throws ParserConfigurationException { - this.output = output; - this.doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - } - - @Override - public void begin() { - root = doc.createElement("testRun"); - doc.appendChild(root); - } - - private Element responseElement(Response r) { - Element responseElem = doc.createElement("response"); - responseElem.setAttribute("successful", r.successful() ? "true" : "false"); - - Element apdu = doc.createElement("apdu"); - apdu.setTextContent(Util.bytesToHex(r.getAPDU().getBytes())); - responseElem.appendChild(apdu); - - Element naturalSW = doc.createElement("natural-sw"); - naturalSW.setTextContent(String.valueOf(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(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 - public void outputResponse(Response r) { - root.appendChild(responseElement(r)); - } - - private Element testElement(Test t) { - Element testElem = doc.createElement("test"); - - if (t instanceof Test.Simple) { - Test.Simple test = (Test.Simple) t; - testElem.setAttribute("type", "simple"); - testElem.appendChild(responseElement(test.getResponse())); - } else if (t instanceof Test.Compound) { - Test.Compound test = (Test.Compound) 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"); - result.setTextContent(t.getResult().toString()); - 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.transform(domSource, result); - } catch (TransformerException e) { - e.printStackTrace(); - } - } -} \ No newline at end of file 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..29a97db --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -0,0 +1,117 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.TestSuite; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +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 Document doc; + private Node root; + + public XMLTestWriter(OutputStream output) throws ParserConfigurationException { + this.output = output; + this.doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } + + @Override + public void begin(TestSuite suite) { + root = doc.createElement("testRun"); + doc.appendChild(root); + } + + private Element responseElement(Response r) { + Element responseElem = doc.createElement("response"); + responseElem.setAttribute("successful", r.successful() ? "true" : "false"); + + Element apdu = doc.createElement("apdu"); + apdu.setTextContent(Util.bytesToHex(r.getAPDU().getBytes())); + responseElem.appendChild(apdu); + + Element naturalSW = doc.createElement("natural-sw"); + naturalSW.setTextContent(String.valueOf(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(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 Test.Simple) { + Test.Simple test = (Test.Simple) t; + testElem.setAttribute("type", "simple"); + testElem.appendChild(responseElement(test.getResponse())); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) 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"); + result.setTextContent(t.getResult().toString()); + 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.transform(domSource, result); + } catch (TransformerException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java deleted file mode 100644 index 211bd47..0000000 --- a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java +++ /dev/null @@ -1,93 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.Util; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.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 class YAMLOutputWriter implements OutputWriter { - private PrintStream output; - private List testRun; - - public YAMLOutputWriter(PrintStream output) { - this.output = output; - } - - @Override - public void begin() { - output.println("---"); - testRun = new LinkedList<>(); - } - - private Map responseObject(Response r) { - Map responseObj = new HashMap<>(); - responseObj.put("successful", r.successful()); - responseObj.put("apdu", Util.bytesToHex(r.getAPDU().getBytes())); - responseObj.put("natural_sw", r.getNaturalSW()); - List sws = new LinkedList<>(); - for (int i = 0; i < r.getNumSW(); ++i) { - sws.add(r.getSW(i)); - } - responseObj.put("sws", sws); - responseObj.put("duration", r.getDuration()); - responseObj.put("desc", r.getDescription()); - return responseObj; - } - - @Override - public void outputResponse(Response r) { - testRun.add(responseObject(r)); - } - - private Map testObject(Test t) { - Map testObj = new HashMap<>(); - - if (t instanceof Test.Simple) { - Test.Simple test = (Test.Simple) t; - testObj.put("type", "simple"); - testObj.put("response", responseObject(test.getResponse())); - } else if (t instanceof Test.Compound) { - Test.Compound test = (Test.Compound) 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()); - testObj.put("result", t.getResult().name()); - - return testObj; - } - - @Override - public void outputTest(Test t) { - testRun.add(testObject(t)); - } - - @Override - public void end() { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - 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/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java new file mode 100644 index 0000000..10d9bb9 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -0,0 +1,92 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.TestSuite; +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 List testRun; + + public YAMLTestWriter(PrintStream output) { + this.output = output; + } + + @Override + public void begin(TestSuite suite) { + output.println("---"); + testRun = new LinkedList<>(); + } + + private Map responseObject(Response r) { + Map responseObj = new HashMap<>(); + responseObj.put("successful", r.successful()); + responseObj.put("apdu", Util.bytesToHex(r.getAPDU().getBytes())); + responseObj.put("natural_sw", r.getNaturalSW()); + List sws = new LinkedList<>(); + for (int i = 0; i < r.getNumSW(); ++i) { + sws.add(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 Test.Simple) { + Test.Simple test = (Test.Simple) t; + testObj.put("type", "simple"); + testObj.put("response", responseObject(test.getResponse())); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) 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()); + testObj.put("result", t.getResult().name()); + + return testObj; + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + testRun.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/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index 75c6371..76b79de 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -8,7 +8,7 @@ import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Curve; import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.output.OutputWriter; +import cz.crcs.ectester.reader.output.TestWriter; import javacard.security.KeyPair; import javax.smartcardio.CardException; @@ -22,12 +22,12 @@ import java.util.Map; */ public class CompositeCurvesSuite extends TestSuite { - public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "composite"); + public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "composite"); } @Override - public List run(CardMngr cardManager) throws IOException, CardException { + 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 @@ -55,6 +55,5 @@ public class CompositeCurvesSuite extends TestSuite { tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } - return super.run(cardManager); } } diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index 2024578..de069f9 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -6,25 +6,21 @@ import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.output.OutputWriter; import javacard.security.KeyPair; -import javax.smartcardio.CardException; import java.io.IOException; -import java.util.List; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class DefaultSuite extends TestSuite { - public DefaultSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "default"); + public DefaultSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "default"); } @Override - public List run(CardMngr cardManager) throws IOException, CardException { + public void setup(CardMngr cardManager) throws IOException { tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); if (cfg.namedCurve != null) { if (cfg.primeField) { @@ -57,7 +53,6 @@ public class DefaultSuite extends TestSuite { } } } - return super.run(cardManager); } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java index 20882b6..3b6cb2f 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -8,10 +8,8 @@ import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Curve; import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.output.OutputWriter; import javacard.security.KeyPair; -import javax.smartcardio.CardException; import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; @@ -19,17 +17,16 @@ import java.util.List; import java.util.Map; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class InvalidCurvesSuite extends TestSuite { - public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "invalid"); + public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "invalid"); } @Override - public List run(CardMngr cardManager) throws CardException, IOException { + 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. */ @@ -64,7 +61,5 @@ public class InvalidCurvesSuite extends TestSuite { } tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } - - return super.run(cardManager); } } diff --git a/src/cz/crcs/ectester/reader/test/TestRunner.java b/src/cz/crcs/ectester/reader/test/TestRunner.java new file mode 100644 index 0000000..baab6a8 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/TestRunner.java @@ -0,0 +1,29 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.reader.output.TestWriter; + +import javax.smartcardio.CardException; + +/** + * @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 CardException { + 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 index fde2266..6123a39 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -1,17 +1,13 @@ package cz.crcs.ectester.reader.test; -import static cz.crcs.ectester.reader.test.Test.Result; 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.ECTester; -import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.*; -import cz.crcs.ectester.reader.output.OutputWriter; -import cz.crcs.ectester.reader.response.Response; -import javacard.security.KeyPair; +import cz.crcs.ectester.reader.output.TestWriter; import javax.smartcardio.CardException; import java.io.IOException; @@ -24,28 +20,16 @@ public abstract class TestSuite { EC_Store dataStore; ECTester.Config cfg; - OutputWriter writer; String name; List tests = new LinkedList<>(); - TestSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer, String name) { + TestSuite(EC_Store dataStore, ECTester.Config cfg, String name) { this.dataStore = dataStore; this.cfg = cfg; - this.writer = writer; this.name = name; } - public List run(CardMngr cardManager) throws CardException, IOException { - writer.begin(); - for (Test t : tests) { - if (!t.hasRun()) { - t.run(); - writer.outputTest(t); - } - } - writer.end(); - return tests; - } + public abstract void setup(CardMngr cardManager) throws IOException; public List getTests() { return Collections.unmodifiableList(tests); diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 2098ae3..2a74d41 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -8,28 +8,25 @@ import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.*; -import cz.crcs.ectester.reader.output.OutputWriter; import cz.crcs.ectester.reader.response.Response; import javacard.security.KeyPair; -import javax.smartcardio.CardException; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Map; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class TestVectorSuite extends TestSuite { - public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "test"); + public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "test"); } @Override - public List run(CardMngr cardManager) throws IOException, CardException { + 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. */ @@ -76,6 +73,5 @@ public class TestVectorSuite extends TestSuite { tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } - return super.run(cardManager); } } diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 3346b9f..95bbe1e 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -3,7 +3,7 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; -import cz.crcs.ectester.reader.output.OutputWriter; +import cz.crcs.ectester.reader.output.TestWriter; import javacard.security.KeyPair; import javax.smartcardio.CardException; @@ -16,12 +16,12 @@ import java.util.List; */ public class WrongCurvesSuite extends TestSuite { - public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "wrong"); + public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "wrong"); } @Override - public List run(CardMngr cardManager) throws CardException, IOException { + 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. */ @@ -31,6 +31,5 @@ public class WrongCurvesSuite extends TestSuite { if (cfg.binaryField) { tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); } - return super.run(cardManager); } } -- cgit v1.3.1 From ca283e0c28ad2050c25f12817db8f8103f1cedc1 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 21:33:31 +0200 Subject: Introduce a Result class, that has a value and a cause. --- src/cz/crcs/ectester/reader/ECTester.java | 10 +-- src/cz/crcs/ectester/reader/Util.java | 10 ++- .../ectester/reader/output/TextTestWriter.java | 4 +- .../crcs/ectester/reader/output/XMLTestWriter.java | 11 ++- .../ectester/reader/output/YAMLTestWriter.java | 3 +- .../ectester/reader/test/CompositeCurvesSuite.java | 21 +++--- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 16 ++--- .../ectester/reader/test/InvalidCurvesSuite.java | 16 ++--- src/cz/crcs/ectester/reader/test/Result.java | 47 +++++++++++++ src/cz/crcs/ectester/reader/test/Test.java | 82 +++++++++++++--------- src/cz/crcs/ectester/reader/test/TestSuite.java | 27 +++---- .../crcs/ectester/reader/test/TestVectorSuite.java | 27 +++---- .../ectester/reader/test/WrongCurvesSuite.java | 6 +- 13 files changed, 177 insertions(+), 103 deletions(-) create mode 100644 src/cz/crcs/ectester/reader/test/Result.java (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 271a8e4..fa71ca6 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -713,8 +713,9 @@ public class ECTester { } format = cli.getOptionValue("format", "text"); - if (!Arrays.asList("text", "xml", "yaml", "yml").contains(format)) { - System.err.println("Wrong output format " + format + "."); + String formats[] = new String[]{"text", "xml", "yaml", "yml"}; + if (!Arrays.asList(formats).contains(format)) { + System.err.println("Wrong output format " + format + ". Should be one of " + Arrays.toString(formats)); return false; } @@ -789,9 +790,8 @@ public class ECTester { testSuite = cli.getOptionValue("test", "default").toLowerCase(); String[] tests = new String[]{"default", "composite", "invalid", "test-vectors", "wrong"}; - List testsList = Arrays.asList(tests); - if (!testsList.contains(testSuite)) { - System.err.println("Unknown test case. Should be one of: " + Arrays.toString(tests)); + if (!Arrays.asList(tests).contains(testSuite)) { + System.err.println("Unknown test suite " + testSuite + ". Should be one of: " + Arrays.toString(tests)); return false; } diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index 754cda3..840f4c5 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -28,15 +28,19 @@ public class Util { array[offset] = (byte) ((value >> 8) & 0xFF); } - public static boolean compareBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) { + public static int diffBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) { for (int i = 0; i < length; ++i) { byte a = one[i + oneOffset]; byte b = other[i + otherOffset]; if (a != b) { - return false; + return i; } } - return true; + return length; + } + + public static boolean compareBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) { + return diffBytes(one, oneOffset, other, otherOffset, length) == length; } public static boolean allValue(byte[] array, byte value) { diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index 80c7204..ca42fba 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.Result; import cz.crcs.ectester.reader.test.TestSuite; import java.io.PrintStream; @@ -19,10 +20,11 @@ public class TextTestWriter implements TestWriter { @Override public void begin(TestSuite suite) { + //TODO: output suite.name and suite.description } private String testPrefix(Test t) { - return String.format("%-4s", t.getResult() == Test.Result.SUCCESS ? "OK" : "NOK"); + return String.format("%-4s", t.getResultValue() == Result.Value.SUCCESS ? "OK" : "NOK"); } private String testString(Test t) { diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index 29a97db..c575bb7 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -8,6 +8,7 @@ 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; @@ -23,17 +24,23 @@ import java.io.OutputStream; */ 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.doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + this.db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } @Override public void begin(TestSuite suite) { - root = doc.createElement("testRun"); + doc = db.newDocument(); + Element rootElem = doc.createElement("testSuite"); + rootElem.setAttribute("name", suite.getName()); + rootElem.setAttribute("desc", suite.getDescription()); + + root = rootElem; doc.appendChild(root); } diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index 10d9bb9..6dc5c2d 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -28,6 +28,7 @@ public class YAMLTestWriter implements TestWriter { public void begin(TestSuite suite) { output.println("---"); testRun = new LinkedList<>(); + //TODO: output suite.name and suite.description } private Map responseObject(Response r) { @@ -63,7 +64,7 @@ public class YAMLTestWriter implements TestWriter { } testObj.put("desc", t.getDescription()); - testObj.put("result", t.getResult().name()); + testObj.put("result", t.getResultValue().name()); return testObj; } diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index 76b79de..291d404 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -8,22 +8,17 @@ import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Curve; import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.output.TestWriter; import javacard.security.KeyPair; -import javax.smartcardio.CardException; -import java.io.IOException; -import java.util.List; import java.util.Map; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class CompositeCurvesSuite extends TestSuite { public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "composite"); + super(dataStore, cfg, "composite", ""); } @Override @@ -44,15 +39,15 @@ public class CompositeCurvesSuite extends TestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.ANY)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.ANY)); - //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); - //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); + //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Result.Value.ANY)); + //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index de069f9..722f375 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -16,18 +16,18 @@ import java.io.IOException; public class DefaultSuite extends TestSuite { public DefaultSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "default"); + 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(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Support(cardManager), Result.Value.ANY)); if (cfg.namedCurve != null) { if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); } } else { if (cfg.all) { @@ -56,11 +56,11 @@ public class DefaultSuite extends TestSuite { } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Result.Value.SUCCESS)); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) - tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); - tests.addAll(defaultCurveTests(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(curve, Result.Value.SUCCESS)); + tests.addAll(defaultCurveTests(cardManager, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java index 3b6cb2f..e8bf3d7 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -22,7 +22,7 @@ import java.util.Map; public class InvalidCurvesSuite extends TestSuite { public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "invalid"); + super(dataStore, cfg, "invalid", ""); } @Override @@ -51,15 +51,15 @@ public class InvalidCurvesSuite extends TestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.SUCCESS)); for (EC_Key.Public pub : keys) { - // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); - // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); + // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.Value.ANY)); + // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Result.Value.FAILURE)); } - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/Result.java b/src/cz/crcs/ectester/reader/test/Result.java new file mode 100644 index 0000000..c6439ef --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/Result.java @@ -0,0 +1,47 @@ +package cz.crcs.ectester.reader.test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class Result { + + private Value value; + private String cause; + + public Result(Value value) { + this.value = value; + } + + public Result(Value value, String cause) { + this(value); + this.cause = cause; + } + + public Value getValue() { + return value; + } + + public String getCause() { + return cause; + } + + public enum Value { + SUCCESS, + FAILURE, + ANY + } + + public boolean compareTo(Result other) { + if (other == null) { + return false; + } + return value == other.value; + } + + public boolean compareTo(Value other) { + if (other == null) { + return false; + } + return value == other; + } +} diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 1890e94..58da891 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -7,6 +7,8 @@ import javax.smartcardio.CardException; import java.util.function.BiFunction; import java.util.function.Function; +import static cz.crcs.ectester.reader.test.Result.Value; + /** * An abstract test that can be run and has a Result. * @@ -23,6 +25,20 @@ public abstract class Test { return result; } + public Value getResultValue() { + if (!hasRun) { + return null; + } + return result.getValue(); + } + + public String getResultCause() { + if (!hasRun) { + return null; + } + return result.getCause(); + } + public abstract String getDescription(); public boolean hasRun() { @@ -31,16 +47,6 @@ public abstract class Test { public abstract void run() throws CardException; - - /** - * A result of a Test. - */ - public enum Result { - SUCCESS, - FAILURE, - ANY - } - /** * A simple test that runs one Command to get and evaluate one Response * to get a Result and compare it with the expected one. @@ -50,18 +56,24 @@ public abstract class Test { private Command command; private Response response; - public Simple(Command command, Result expected) { + public Simple(Command command, BiFunction callback) { + this.command = command; + this.callback = callback; + } + + public Simple(Command command, Value expected, String ok, String nok) { this(command, (cmd, resp) -> { - if (expected == Result.ANY) - return Result.SUCCESS; - Result respResult = resp.successful() ? Result.SUCCESS : Result.FAILURE; - return respResult == expected ? Result.SUCCESS : Result.FAILURE; + if (expected == Value.ANY) { + return new Result(Value.SUCCESS, ok); + } + Value respResult = resp.successful() ? Value.SUCCESS : Value.FAILURE; + boolean cond = expected == respResult; + return new Result(cond ? Value.SUCCESS : Value.FAILURE, cond ? ok : nok); }); } - public Simple(Command command, BiFunction callback) { - this.command = command; - this.callback = callback; + public Simple(Command command, Value expected) { + this(command, expected, null, null); } public Command getCommand() { @@ -82,9 +94,9 @@ public abstract class Test { result = callback.apply(command, response); } else { if (response.successful()) { - result = Result.SUCCESS; + result = new Result(Value.SUCCESS); } else { - result = Result.FAILURE; + result = new Result(Value.FAILURE); } } hasRun = true; @@ -122,52 +134,52 @@ public abstract class Test { return new Compound(callback, description, tests); } - public static Compound all(Result what, Test... all) { + public static Compound all(Value what, Test... all) { return new Compound((tests) -> { for (Test test : tests) { - if (test.getResult() != what) { - return Result.FAILURE; + if (test.getResultValue() != what) { + return new Result(Value.FAILURE); } } - return Result.SUCCESS; + return new Result(Value.SUCCESS); }, all); } - public static Compound all(Result what, String description, Test... all) { + public static Compound all(Value what, String description, Test... all) { Compound result = Compound.all(what, all); result.setDescription(description); return result; } - public static Compound any(Result what, Test... any) { + public static Compound any(Value what, Test... any) { return new Compound((tests) -> { for (Test test : tests) { - if (test.getResult() == what) { - return Result.SUCCESS; + if (test.getResultValue() == what) { + return new Result(Value.SUCCESS); } } - return Result.FAILURE; + return new Result(Value.FAILURE); }, any); } - public static Compound any(Result what, String description, Test... any) { + public static Compound any(Value what, String description, Test... any) { Compound result = Compound.any(what, any); result.setDescription(description); return result; } - public static Compound mask(Result[] results, Test... masked) { + public static Compound mask(Value[] results, Test... masked) { return new Compound((tests) -> { for (int i = 0; i < results.length; ++i) { - if (results[i] != Result.ANY && results[i] != tests[i].getResult()) { - return Result.FAILURE; + if (results[i] != Value.ANY && results[i] != tests[i].getResultValue()) { + return new Result(Value.FAILURE); } } - return Result.SUCCESS; + return new Result(Value.SUCCESS); }, masked); } - public static Compound mask(Result[] results, String description, Test... masked) { + public static Compound mask(Value[] results, String description, Test... masked) { Compound result = Compound.mask(results, masked); result.setDescription(description); return result; diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 6123a39..3b8476f 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -7,9 +7,7 @@ import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.*; -import cz.crcs.ectester.reader.output.TestWriter; -import javax.smartcardio.CardException; import java.io.IOException; import java.util.*; @@ -17,16 +15,17 @@ import java.util.*; * @author Jan Jancar johny@neuromancer.sk */ public abstract class TestSuite { - EC_Store dataStore; ECTester.Config cfg; String name; + String description; List tests = new LinkedList<>(); - TestSuite(EC_Store dataStore, ECTester.Config cfg, String name) { + TestSuite(EC_Store dataStore, ECTester.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; @@ -39,6 +38,10 @@ public abstract class TestSuite { return name; } + public String getDescription() { + return description; + } + /** * @param cardManager cardManager to send APDU through * @param generateExpected expected result of the Generate command @@ -46,16 +49,16 @@ public abstract class TestSuite { * @param ecdsaExpected expected result of the ordinary ECDSA command * @return tests to run */ - List defaultCurveTests(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdsaExpected) { List tests = new LinkedList<>(); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Result.Value.FAILURE)); tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return tests; @@ -71,7 +74,7 @@ public abstract class TestSuite { * @param ecdsaExpected expected result of the ordinary ECDSA command * @return tests to run */ - List defaultCategoryTests(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List defaultCategoryTests(CardMngr cardManager, String category, byte field, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdsaExpected) { List tests = new LinkedList<>(); Map curves = dataStore.getObjects(EC_Curve.class, category); if (curves == null) @@ -79,10 +82,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 Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Result.Value.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); tests.addAll(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 2a74d41..4a91940 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -22,7 +22,7 @@ import java.util.Map; public class TestVectorSuite extends TestSuite { public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "test"); + super(dataStore, cfg, "test", ""); } @Override @@ -55,22 +55,25 @@ public class TestVectorSuite extends TestSuite { } List testVector = new LinkedList<>(); - testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); + //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Result.Value.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Result.Value.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Result.Value.SUCCESS)); testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> { Response.ECDH dh = (Response.ECDH) response; - if (!dh.successful() || !dh.hasSecret()) - return Test.Result.FAILURE; + if (!dh.successful()) + return new Result(Result.Value.FAILURE, "ECDH was unsuccessful."); + if (!dh.hasSecret()) + return new Result(Result.Value.FAILURE, "ECDH response did not contain the derived secret."); if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { - return Test.Result.FAILURE; + int firstDiff = Util.diffBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength()); + return new Result(Result.Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); } - return Test.Result.SUCCESS; + return new Result(Result.Value.SUCCESS); })); - tests.add(Test.Compound.all(Test.Result.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(Test.Compound.all(Result.Value.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 95bbe1e..307a16a 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -17,7 +17,7 @@ import java.util.List; public class WrongCurvesSuite extends TestSuite { public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "wrong"); + super(dataStore, cfg, "wrong", ""); } @Override @@ -26,10 +26,10 @@ public class WrongCurvesSuite extends TestSuite { * These should generally fail, the curves aren't curves. */ if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE)); } } } -- cgit v1.3.1 From 567695b16aef0f0706f46f0a87c83baae808b47e Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 31 Oct 2017 21:18:09 +0100 Subject: Add compound test to default tests. --- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 7 +- src/cz/crcs/ectester/reader/test/TestSuite.java | 74 ++++++++++++++++------ .../ectester/reader/test/WrongCurvesSuite.java | 5 +- 3 files changed, 63 insertions(+), 23 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index 722f375..8fea661 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -23,11 +23,12 @@ public class DefaultSuite extends TestSuite { public void setup(CardMngr cardManager) throws IOException { tests.add(new Test.Simple(new Command.Support(cardManager), Result.Value.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, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, desc)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, desc)); } } else { if (cfg.all) { @@ -60,7 +61,7 @@ public class DefaultSuite extends TestSuite { Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) tests.add(new Test.Simple(curve, Result.Value.SUCCESS)); - tests.addAll(defaultCurveTests(cardManager, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); + tests.add(defaultCurveTests(cardManager, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, "Default tests.")); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 3b8476f..c0e8e91 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -6,10 +6,14 @@ import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.ec.*; +import cz.crcs.ectester.reader.ec.EC_Curve; import java.io.IOException; -import java.util.*; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; /** * @author Jan Jancar johny@neuromancer.sk @@ -43,13 +47,15 @@ public abstract class TestSuite { } /** - * @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 ecdsaExpected expected result of the ordinary ECDSA command - * @return tests to run + * @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 */ - List defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdsaExpected) { + Test defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressExpected, Result.Value ecdsaExpected, String description) { List tests = new LinkedList<>(); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); @@ -61,20 +67,52 @@ public abstract class TestSuite { tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Result.Value.FAILURE)); tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); - return tests; + return Test.Compound.function((testArray) -> { + Function shouldHave = (expected) -> { + switch (expected) { + case SUCCESS: + return "been successful"; + case FAILURE: + return "failed"; + case ANY: + default: + return ""; + } + }; + + for (int i = 0; i < testArray.length; ++i) { + Test t = testArray[i]; + if (t.getResultValue() != Result.Value.SUCCESS) { + if (i == 0) { // generate + return new Result(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(Result.Value.FAILURE, "The ECDH should have " + shouldHave.apply(ecdhExpected) + ", but it did not."); + } else if (i == 1) { // ecdh normal + return new Result(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(Result.Value.FAILURE, "The ECDH of a corrupted point should have failed, but it dit not."); + } else { // ecdsa + return new Result(Result.Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); + } + } + } + return new Result(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 ecdsaExpected expected result of the ordinary ECDSA command + * @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 + * @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, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdsaExpected) { + List defaultCategoryTests(CardMngr cardManager, String category, byte field, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressedExpected, Result.Value ecdsaExpected, String description) { List tests = new LinkedList<>(); Map curves = dataStore.getObjects(EC_Curve.class, category); if (curves == null) @@ -84,7 +122,7 @@ public abstract class TestSuite { if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Result.Value.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); - tests.addAll(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); + tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 76fc9d9..20cb405 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -21,11 +21,12 @@ public class WrongCurvesSuite extends TestSuite { /* 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, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, desc)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, desc)); } } } -- cgit v1.3.1 From daaa7abd91ff8ae12e0b1835045489acbda0539f Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 5 Nov 2017 16:48:30 +0100 Subject: Implement Result.ExpectedValue to add more logic to test evaluation. - Introduces a new enum Result.ExpectedValue, which is used to signify what Test results are expected. - Changes the Result.Value enum to contain information about what was expected. It gains more values: - UXSUCCESS -> Unexpected success. - XFAILURE -> Expected failure. The values SUCCESS and XFAILURE are the OK, values. - Creates a hierarchy of evaluating Responses, Simple tests and Compoung tests. Simple test evaluates the OK property of the response object (using .successfull() method) and again exposes its OK property which depends on the tests ExpectedValue and the response success. Compound test evaluates the OK property of the Simple tests it contains (using the .ok() method) and again exposes its OK property which depends on the concrete Compound test variant, but involves some ExpectedValues and the success of the individual Simple tests it contains. --- .../ectester/reader/output/ResponseWriter.java | 2 +- .../ectester/reader/output/TextTestWriter.java | 50 +++++++++++++++------- .../crcs/ectester/reader/output/XMLTestWriter.java | 3 ++ .../ectester/reader/output/YAMLTestWriter.java | 3 +- .../ectester/reader/test/CompositeCurvesSuite.java | 12 +++--- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 16 ++++--- .../ectester/reader/test/InvalidCurvesSuite.java | 14 +++--- src/cz/crcs/ectester/reader/test/Result.java | 33 ++++++++++++++ src/cz/crcs/ectester/reader/test/Test.java | 38 ++++++++-------- src/cz/crcs/ectester/reader/test/TestSuite.java | 39 +++++++++-------- .../crcs/ectester/reader/test/TestVectorSuite.java | 25 ++++++----- .../ectester/reader/test/WrongCurvesSuite.java | 6 ++- 12 files changed, 157 insertions(+), 84 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/output/ResponseWriter.java b/src/cz/crcs/ectester/reader/output/ResponseWriter.java index ee5d652..0f932e7 100644 --- a/src/cz/crcs/ectester/reader/output/ResponseWriter.java +++ b/src/cz/crcs/ectester/reader/output/ResponseWriter.java @@ -26,7 +26,7 @@ public class ResponseWriter { if (suffix.length() == 0) { suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]"); } - return String.format("%4d ms : %s", r.getDuration() / 1000000, suffix); + return String.format("%4d ms ┃ %s", r.getDuration() / 1000000, suffix); } public void outputResponse(Response r) { diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index dedefe6..d697761 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -1,7 +1,6 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.reader.test.Test; -import cz.crcs.ectester.reader.test.Result; import cz.crcs.ectester.reader.test.TestSuite; import java.io.PrintStream; @@ -13,6 +12,8 @@ public class TextTestWriter implements TestWriter { private PrintStream output; private ResponseWriter respWriter; + public static int BASE_WIDTH = 72; + public TextTestWriter(PrintStream output) { this.output = output; this.respWriter = new ResponseWriter(output); @@ -24,34 +25,51 @@ public class TextTestWriter implements TestWriter { output.println("=== " + suite.getDescription()); } - private String testPrefix(Test t) { - return String.format("%-4s", t.getResultValue() == Result.Value.SUCCESS ? "OK" : "NOK"); - } - private String testString(Test t) { - if (!t.hasRun()) + private String testString(Test t, int offset) { + if (!t.hasRun()) { return null; + } StringBuilder out = new StringBuilder(); if (t instanceof Test.Simple) { Test.Simple test = (Test.Simple) t; - out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())).append(" : "); + 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 if (t instanceof Test.Compound) { + } else { + out.append(System.lineSeparator()); Test.Compound test = (Test.Compound) 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 == 0) { - out.append(" /- "); - } else if (i == tests.length - 1) { - out.append(" \\- "); + if (i == tests.length - 1) { + out.append(" ┗ "); } else { - out.append(" | "); + out.append(" ┣ "); + } + out.append(testString(tests[i], offset + 6)); + if (i != tests.length - 1) { + out.append(System.lineSeparator()); } - out.append(testString(tests[i])).append(System.lineSeparator()); } - out.append(String.format("%-70s", testPrefix(t) + " : " + test.getDescription())); } + return out.toString(); } @@ -59,7 +77,7 @@ public class TextTestWriter implements TestWriter { public void outputTest(Test t) { if (!t.hasRun()) return; - output.println(testString(t)); + output.println(testString(t, 0)); output.flush(); } diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index b4accdd..709d215 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -107,10 +107,13 @@ public class XMLTestWriter implements TestWriter { 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); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index 93e2b45..f0dcd3a 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -80,7 +80,8 @@ public class YAMLTestWriter implements TestWriter { } testObj.put("desc", t.getDescription()); - Map result = new HashMap<>(); + Map result = new HashMap<>(); + result.put("ok", t.ok()); result.put("value", t.getResultValue().name()); result.put("cause", t.getResultCause()); testObj.put("result", result); diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index c777a77..8e7ca31 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -12,6 +12,8 @@ import javacard.security.KeyPair; import java.util.Map; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -39,12 +41,12 @@ public class CompositeCurvesSuite extends TestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.ANY)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.ANY)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()); - tests.add(new Test.Simple(ecdhCommand, Result.Value.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(new Test.Simple(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index 8fea661..736b7c5 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -10,6 +10,8 @@ import javacard.security.KeyPair; import java.io.IOException; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -21,14 +23,14 @@ public class DefaultSuite extends TestSuite { @Override public void setup(CardMngr cardManager) throws IOException { - tests.add(new Test.Simple(new Command.Support(cardManager), Result.Value.ANY)); + tests.add(new Test.Simple(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, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, desc)); + 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, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, desc)); + 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) { @@ -57,11 +59,11 @@ public class DefaultSuite extends TestSuite { } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) - tests.add(new Test.Simple(curve, Result.Value.SUCCESS)); - tests.add(defaultCurveTests(cardManager, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, "Default tests.")); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(new Test.Simple(curve, ExpectedValue.SUCCESS)); + tests.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default tests.")); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java index 229a5a3..f61b695 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -16,6 +16,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -51,16 +53,16 @@ public class InvalidCurvesSuite extends TestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); 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 Test.Simple(ecdhCommand, Result.Value.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); + ecdhTests.add(new Test.Simple(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); } - tests.add(Test.Compound.all(Result.Value.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(Test.Compound.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/Result.java b/src/cz/crcs/ectester/reader/test/Result.java index c6439ef..9110929 100644 --- a/src/cz/crcs/ectester/reader/test/Result.java +++ b/src/cz/crcs/ectester/reader/test/Result.java @@ -25,7 +25,40 @@ public class Result { return cause; } + public boolean ok() { + return value.ok(); + } + public enum Value { + SUCCESS(true), + FAILURE(false), + UXSUCCESS(false), + XFAILURE(true); + + private boolean ok; + + Value(boolean ok) { + this.ok = ok; + } + + public static Value fromExpected(ExpectedValue expected, boolean successful) { + switch (expected) { + case SUCCESS: + return successful ? SUCCESS : FAILURE; + case FAILURE: + return successful ? UXSUCCESS : XFAILURE; + case ANY: + return SUCCESS; + } + return SUCCESS; + } + + public boolean ok() { + return ok; + } + } + + public enum ExpectedValue { SUCCESS, FAILURE, ANY diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 3848df2..48280ed 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -7,6 +7,7 @@ import javax.smartcardio.CardException; import java.util.function.BiFunction; import java.util.function.Function; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; import static cz.crcs.ectester.reader.test.Result.Value; /** @@ -39,6 +40,13 @@ public abstract class Test { return result.getCause(); } + public boolean ok() { + if (!hasRun) { + return true; + } + return result.ok(); + } + public abstract String getDescription(); public boolean hasRun() { @@ -61,18 +69,14 @@ public abstract class Test { this.callback = callback; } - public Simple(Command command, Value expected, String ok, String nok) { + public Simple(Command command, ExpectedValue expected, String ok, String nok) { this(command, (cmd, resp) -> { - if (expected == Value.ANY) { - return new Result(Value.SUCCESS, ok); - } - Value respResult = resp.successful() ? Value.SUCCESS : Value.FAILURE; - boolean cond = expected == respResult; - return new Result(cond ? Value.SUCCESS : Value.FAILURE, cond ? ok : nok); + Value resultValue = Value.fromExpected(expected, resp.successful()); + return new Result(resultValue, resultValue.ok() ? ok : nok); }); } - public Simple(Command command, Value expected) { + public Simple(Command command, ExpectedValue expected) { this(command, expected, null, null); } @@ -134,10 +138,10 @@ public abstract class Test { return new Compound(callback, description, tests); } - public static Compound all(Value what, Test... all) { + public static Compound all(ExpectedValue what, Test... all) { return new Compound((tests) -> { for (Test test : tests) { - if (test.getResultValue() != what) { + if (!Value.fromExpected(what, test.ok()).ok()) { return new Result(Value.FAILURE, "At least one of the sub-tests did not have the expected result."); } } @@ -145,16 +149,16 @@ public abstract class Test { }, all); } - public static Compound all(Value what, String description, Test... all) { + public static Compound all(ExpectedValue what, String description, Test... all) { Compound result = Compound.all(what, all); result.setDescription(description); return result; } - public static Compound any(Value what, Test... any) { + public static Compound any(ExpectedValue what, Test... any) { return new Compound((tests) -> { for (Test test : tests) { - if (test.getResultValue() == what) { + if (Value.fromExpected(what, test.ok()).ok()) { return new Result(Value.SUCCESS, "At least one of the sub-tests did have the expected result."); } } @@ -162,16 +166,16 @@ public abstract class Test { }, any); } - public static Compound any(Value what, String description, Test... any) { + public static Compound any(ExpectedValue what, String description, Test... any) { Compound result = Compound.any(what, any); result.setDescription(description); return result; } - public static Compound mask(Value[] results, Test... masked) { + public static Compound mask(ExpectedValue[] results, Test... masked) { return new Compound((tests) -> { for (int i = 0; i < results.length; ++i) { - if (results[i] != Value.ANY && results[i] != tests[i].getResultValue()) { + if (!Value.fromExpected(results[i], tests[i].ok()).ok()) { return new Result(Value.FAILURE, "At least one of the sub-tests did not match the result mask."); } } @@ -179,7 +183,7 @@ public abstract class Test { }, masked); } - public static Compound mask(Value[] results, String description, Test... masked) { + public static Compound mask(ExpectedValue[] results, String description, Test... masked) { Compound result = Compound.mask(results, masked); result.setDescription(description); return result; diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index c0e8e91..cb3211d 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -15,6 +15,9 @@ import java.util.List; import java.util.Map; import java.util.function.Function; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; +import static cz.crcs.ectester.reader.test.Result.Value; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -55,23 +58,23 @@ public abstract class TestSuite { * @param description compound test description * @return test to run */ - Test defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressExpected, Result.Value ecdsaExpected, String description) { + Test defaultCurveTests(CardMngr cardManager, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressExpected, ExpectedValue ecdsaExpected, String description) { List tests = new LinkedList<>(); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return Test.Compound.function((testArray) -> { - Function shouldHave = (expected) -> { + Function shouldHave = (expected) -> { switch (expected) { case SUCCESS: - return "been successful"; + return "succeeded"; case FAILURE: return "failed"; case ANY: @@ -82,21 +85,21 @@ public abstract class TestSuite { for (int i = 0; i < testArray.length; ++i) { Test t = testArray[i]; - if (t.getResultValue() != Result.Value.SUCCESS) { + if (!t.ok()) { if (i == 0) { // generate - return new Result(Result.Value.FAILURE, "The generation of a key should have " + shouldHave.apply(generateExpected) + ", but it did not."); + 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(Result.Value.FAILURE, "The ECDH should have " + shouldHave.apply(ecdhExpected) + ", but it did not."); + 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(Result.Value.FAILURE, "The ECDH of a compressed point should have " + shouldHave.apply(ecdhCompressExpected) + ", but it did not."); + 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(Result.Value.FAILURE, "The ECDH of a corrupted point should have failed, but it dit not."); + return new Result(Value.FAILURE, "The ECDH of a corrupted point should have failed, but it dit not."); } else { // ecdsa - return new Result(Result.Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); + return new Result(Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); } } } - return new Result(Result.Value.SUCCESS); + return new Result(Value.SUCCESS); }, description, tests.toArray(new Test[0])); } @@ -107,12 +110,12 @@ public abstract class TestSuite { * @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 + * @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, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressedExpected, Result.Value ecdsaExpected, String description) { + 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) @@ -120,10 +123,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 Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(new Test.Simple(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 7a2767e..ff46feb 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -16,6 +16,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; +import static cz.crcs.ectester.reader.test.Result.Value; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -55,25 +58,25 @@ public class TestVectorSuite extends TestSuite { } List testVector = new LinkedList<>(); - testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); - //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Result.Value.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Result.Value.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Result.Value.SUCCESS)); + testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> { Response.ECDH dh = (Response.ECDH) response; if (!dh.successful()) - return new Result(Result.Value.FAILURE, "ECDH was unsuccessful."); + return new Result(Value.FAILURE, "ECDH was unsuccessful."); if (!dh.hasSecret()) - return new Result(Result.Value.FAILURE, "ECDH response did not contain the derived secret."); + return new Result(Value.FAILURE, "ECDH response did not contain the derived secret."); if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { int firstDiff = Util.diffBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength()); - return new Result(Result.Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); + return new Result(Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); } - return new Result(Result.Value.SUCCESS); + return new Result(Value.SUCCESS); })); - tests.add(Test.Compound.all(Result.Value.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(Test.Compound.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 20cb405..e9389b4 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -7,6 +7,8 @@ import javacard.security.KeyPair; import java.io.IOException; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -23,10 +25,10 @@ public class WrongCurvesSuite extends TestSuite { */ String desc = "Default tests over wrong curve params."; if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, desc)); + 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, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, desc)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); } } } -- cgit v1.3.1 From ffe19211aebfd26f9c7bb404903e2a4c2da075db Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 6 Nov 2017 21:09:36 +0100 Subject: Output SWs as unsigned ints. --- src/cz/crcs/ectester/reader/output/XMLTestWriter.java | 4 ++-- .../crcs/ectester/reader/output/YAMLTestWriter.java | 6 +++--- src/cz/crcs/ectester/reader/test/TestSuite.java | 2 +- src/cz/crcs/ectester/scripts/ectester.sh | 19 +++++++++++-------- 4 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/TestSuite.java') diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index 709d215..beb758c 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -64,13 +64,13 @@ public class XMLTestWriter implements TestWriter { responseElem.appendChild(apdu); Element naturalSW = doc.createElement("natural-sw"); - naturalSW.setTextContent(String.valueOf(r.getNaturalSW())); + 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(r.getSW(i))); + sw.setTextContent(String.valueOf(Short.toUnsignedInt(r.getSW(i)))); sws.appendChild(sw); } responseElem.appendChild(sws); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index f0dcd3a..3b2b72d 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -50,10 +50,10 @@ public class YAMLTestWriter implements TestWriter { Map responseObj = new HashMap<>(); responseObj.put("successful", r.successful()); responseObj.put("apdu", Util.bytesToHex(r.getAPDU().getBytes())); - responseObj.put("natural_sw", r.getNaturalSW()); - List sws = new LinkedList<>(); + responseObj.put("natural_sw", Short.toUnsignedInt(r.getNaturalSW())); + List sws = new LinkedList<>(); for (int i = 0; i < r.getNumSW(); ++i) { - sws.add(r.getSW(i)); + sws.add(Short.toUnsignedInt(r.getSW(i))); } responseObj.put("sws", sws); responseObj.put("duration", r.getDuration()); diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index cb3211d..f13317c 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -93,7 +93,7 @@ public abstract class TestSuite { } 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 dit not."); + 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."); } diff --git a/src/cz/crcs/ectester/scripts/ectester.sh b/src/cz/crcs/ectester/scripts/ectester.sh index 0de1bc3..8040096 100755 --- a/src/cz/crcs/ectester/scripts/ectester.sh +++ b/src/cz/crcs/ectester/scripts/ectester.sh @@ -20,12 +20,15 @@ esac done set -- "${positional[@]}" -if [[ $# -ne 1 ]]; then - echo "One argument expected:" >&2 - echo " ./ectester.sh [--dangerous] CARD_NAME" >&2 +if [[ $# -lt 1 ]]; then + echo "At least one argument expected:" >&2 + echo " ./ectester.sh [--dangerous] CARD_NAME [ECTester args]" >&2 exit 1 fi +card="$1" +shift + declare -a tests=("default" "test-vectors") if [[ "$dangerous" == "1" ]]; then tests+=("invalid" "wrong" "composite") @@ -34,12 +37,12 @@ fi declare -a files=() for i in $(seq 0 $((${#tests[@]} - 1))); do test="${tests[$i]}" - java -jar ECTester.jar -t ${test} -a --format yaml -l ${1}.${test} - files+=(${1}.$test) + java -jar ECTester.jar -t ${test} -a --format yaml -l ${card}.${test} $@ + files+=(${card}.$test) done if command -v tar 2>&1 >/dev/null; then - tar -czvf ${1}.tar.gz ${files[*]} + tar -czvf ${card}.tar.gz ${files[*]} elif command -v zip 2>&1 >/dev/null; then - zip ${1}.zip ${files[*]} -fi \ No newline at end of file + zip ${card}.zip ${files[*]} +fi -- cgit v1.3.1