diff options
| author | J08nY | 2018-01-09 13:46:29 +0100 |
|---|---|---|
| committer | J08nY | 2018-01-09 13:46:29 +0100 |
| commit | 94e441b522069d3fed4b88a4823b91c1593bac68 (patch) | |
| tree | 6b8ebc96c50b7a16acdc71c74a34daa7669187a9 | |
| parent | d19d8ad062a3c0053789eae5f7c9662399f781e0 (diff) | |
| download | ECTester-94e441b522069d3fed4b88a4823b91c1593bac68.tar.gz ECTester-94e441b522069d3fed4b88a4823b91c1593bac68.tar.zst ECTester-94e441b522069d3fed4b88a4823b91c1593bac68.zip | |
19 files changed, 265 insertions, 294 deletions
diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 870fb3d..71d9d56 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -83,7 +83,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte KeyAgreement_ALG_EC_SVDP_DHC_PLAIN = 4; public static final byte KeyAgreement_ALG_EC_PACE_GM = 5; public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6; - public static final byte KeyAgreement_ALG_DH_PLAIN = 7; // Class javacard.security.Signature // javacard.security.Signature Fields: diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 15cb7fa..4581fd6 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -1002,7 +1002,7 @@ public class EC_Consts { public static final byte CURVE_default = (byte) 0; public static final byte CURVE_external = (byte) 0xff; - // SECP recommended curves over FP + // SECG recommended curves over FP public static final byte CURVE_secp112r1 = (byte) 1; public static final byte CURVE_secp128r1 = (byte) 2; public static final byte CURVE_secp160r1 = (byte) 3; @@ -1014,7 +1014,7 @@ public class EC_Consts { public static final byte FP_CURVES = (byte) 8; - // SECP recommended curves over F2M + // SECG recommended curves over F2M public static final byte CURVE_sect163r1 = (byte) 9; public static final byte CURVE_sect233r1 = (byte) 10; public static final byte CURVE_sect283r1 = (byte) 11; @@ -1026,6 +1026,25 @@ public class EC_Consts { public static final short[] FP_SIZES = new short[]{112, 128, 160, 192, 224, 256, 384, 521}; public static final short[] F2M_SIZES = new short[]{163, 233, 283, 409, 571}; + public static final byte[] KA_TYPES = new byte[]{ + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, + //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_KDF, //duplicate + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC, + //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_KDF, //duplicate + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN, + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN, + ECTesterApplet.KeyAgreement_ALG_EC_PACE_GM, + ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY + }; + + public static final byte[] SIG_TYPES = new byte[]{ + ECTesterApplet.Signature_ALG_ECDSA_SHA, + ECTesterApplet.Signature_ALG_ECDSA_SHA_224, + ECTesterApplet.Signature_ALG_ECDSA_SHA_256, + ECTesterApplet.Signature_ALG_ECDSA_SHA_384, + ECTesterApplet.Signature_ALG_ECDSA_SHA_512 + }; + public static byte getCurve(short keyLength, byte keyClass) { if (keyClass == KeyPair.ALG_EC_FP) { switch (keyLength) { diff --git a/src/cz/crcs/ectester/common/cli/TreeParser.java b/src/cz/crcs/ectester/common/cli/TreeParser.java index 77cce30..f1a1980 100644 --- a/src/cz/crcs/ectester/common/cli/TreeParser.java +++ b/src/cz/crcs/ectester/common/cli/TreeParser.java @@ -86,6 +86,7 @@ public class TreeParser implements CommandLineParser { } } + int maxArgs = args.size(); long requiredArgs = args.stream().filter(Argument::isRequired).count(); String reqArgs = String.join(" ", args.stream().filter(Argument::isRequired).map(Argument::getName).collect(Collectors.toList())); @@ -99,6 +100,8 @@ public class TreeParser implements CommandLineParser { if (lastCli.getArgs().length < requiredArgs) { throw new MissingArgumentException("Not enough arguments: " + reqArgs); + } else if (lastCli.getArgs().length > maxArgs) { + throw new MissingArgumentException("Too many arguments."); } subTreeCli.setName(sub); @@ -106,6 +109,8 @@ public class TreeParser implements CommandLineParser { } else if (subCli != null) { if (subCli.getArgs().length < requiredArgs) { throw new MissingArgumentException("Not enough arguments: " + reqArgs); + } else if (subCli.getArgs().length > maxArgs) { + throw new MissingArgumentException("Too many arguments."); } TreeCommandLine subTreeCli = new TreeCommandLine(sub, subCli, null); @@ -113,7 +118,10 @@ public class TreeParser implements CommandLineParser { } else { if (cliArgs.length < requiredArgs) { throw new MissingArgumentException("Not enough arguments: " + reqArgs); + } else if (cliArgs.length > maxArgs) { + throw new MissingArgumentException("Too many arguments."); } + return new TreeCommandLine(cli, null); } } diff --git a/src/cz/crcs/ectester/common/test/BaseRunnable.java b/src/cz/crcs/ectester/common/test/BaseRunnable.java deleted file mode 100644 index 3e18208..0000000 --- a/src/cz/crcs/ectester/common/test/BaseRunnable.java +++ /dev/null @@ -1,31 +0,0 @@ -package cz.crcs.ectester.common.test; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class BaseRunnable implements Runnable { - private boolean hasRun = false; - private Func runImplicit; - - public BaseRunnable(Func runImplicit) { - this.runImplicit = runImplicit; - } - - @Override - public boolean hasRun() { - return hasRun; - } - - @Override - public void run() throws TestException { - if (!hasRun) { - runImplicit.run(); - } - hasRun = true; - } - - @FunctionalInterface - public interface Func { - void run() throws TestException; - } -} diff --git a/src/cz/crcs/ectester/common/test/Runnable.java b/src/cz/crcs/ectester/common/test/Runnable.java deleted file mode 100644 index 6f0efb0..0000000 --- a/src/cz/crcs/ectester/common/test/Runnable.java +++ /dev/null @@ -1,18 +0,0 @@ -package cz.crcs.ectester.common.test; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public interface Runnable { - /** - * @return Whether this runnable was run. - */ - boolean hasRun(); - - /** - * Run this Runnable. - * - * @throws TestException - */ - void run() throws TestException; -} diff --git a/src/cz/crcs/ectester/common/test/TestRunner.java b/src/cz/crcs/ectester/common/test/TestRunner.java deleted file mode 100644 index cd71bcd..0000000 --- a/src/cz/crcs/ectester/common/test/TestRunner.java +++ /dev/null @@ -1,29 +0,0 @@ -package cz.crcs.ectester.common.test; - -import cz.crcs.ectester.common.output.TestWriter; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TestRunner { - private TestSuite suite; - private TestWriter writer; - - public TestRunner(TestSuite suite, TestWriter writer) { - this.suite = suite; - this.writer = writer; - } - - public void run() throws TestException { - writer.begin(suite); - for (Runnable t : suite.getRunnables()) { - if (!t.hasRun()) { - t.run(); - if (t instanceof Test) { - writer.outputTest((Test) t); - } - } - } - writer.end(); - } -} diff --git a/src/cz/crcs/ectester/common/test/TestSuite.java b/src/cz/crcs/ectester/common/test/TestSuite.java index 1a7c914..f4f30ee 100644 --- a/src/cz/crcs/ectester/common/test/TestSuite.java +++ b/src/cz/crcs/ectester/common/test/TestSuite.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.common.test; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.data.EC_Store; import java.util.Collections; @@ -13,27 +14,37 @@ import java.util.stream.Collectors; public abstract class TestSuite { protected String name; protected String description; - protected List<Runnable> run = new LinkedList<>(); - protected EC_Store dataStore; + protected TestWriter writer; - public TestSuite(EC_Store dataStore, String name, String description) { - this.dataStore = dataStore; + public TestSuite(TestWriter writer, String name, String description) { + this.writer = writer; this.name = name; this.description = description; } - public List<Runnable> getRunnables() { - return Collections.unmodifiableList(run); + public void run() throws TestException { + writer.begin(this); + try { + runTests(); + } catch (Exception e) { + throw new TestException(e); + } + writer.end(); } - @SuppressWarnings("unchecked") - public List<Test> getTests() { - return Collections.unmodifiableList((List<Test>)(List<?>) run - .stream() - .filter(runnable -> (runnable instanceof Test)) - .collect(Collectors.toList())); + protected Test runTest(Test t) throws TestException { + t.run(); + return t; } + protected Test doTest(Test t) throws TestException { + t.run(); + writer.outputTest(t); + return t; + } + + protected abstract void runTests() throws Exception; + public String getName() { return name; } diff --git a/src/cz/crcs/ectester/common/test/Testable.java b/src/cz/crcs/ectester/common/test/Testable.java index cc7a5de..3627075 100644 --- a/src/cz/crcs/ectester/common/test/Testable.java +++ b/src/cz/crcs/ectester/common/test/Testable.java @@ -3,7 +3,7 @@ package cz.crcs.ectester.common.test; /** * @author Jan Jancar johny@neuromancer.sk */ -public interface Testable extends Runnable { +public interface Testable { /** * @return Whether this Testable was OK. */ @@ -13,4 +13,15 @@ public interface Testable extends Runnable { * @return Whether an error happened. */ boolean error(); + /** + * @return Whether this runnable was run. + */ + boolean hasRun(); + + /** + * Run this Runnable. + * + * @throws TestException + */ + void run() throws TestException; } diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index c25be4e..e4ba40c 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -1,8 +1,6 @@ package cz.crcs.ectester.data; -import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.*; -import cz.crcs.ectester.common.util.CardUtil; import javacard.security.KeyPair; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -31,12 +29,11 @@ import java.util.TreeMap; * @author Jan Jancar johny@neuromancer.sk */ public class EC_Store { - private DocumentBuilder db; - private Map<String, EC_Category> categories; + private static EC_Store instance; - public EC_Store() throws IOException { + private EC_Store() { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { @@ -85,7 +82,7 @@ public class EC_Store { }); parse(); - } catch (ParserConfigurationException | SAXException e) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } } @@ -322,4 +319,11 @@ public class EC_Store { return getObject(objClass, query.substring(0, split), query.substring(split + 1)); } + public static EC_Store getInstance() { + if (instance == null) { + instance = new EC_Store(); + } + return instance; + } + } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index d4b95ed..ff0f403 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -28,7 +28,6 @@ import cz.crcs.ectester.common.ec.EC_Params; import cz.crcs.ectester.common.output.OutputLogger; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestException; -import cz.crcs.ectester.common.test.TestRunner; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.common.util.CardUtil; import cz.crcs.ectester.data.EC_Store; @@ -64,9 +63,7 @@ import static cz.crcs.ectester.applet.ECTesterApplet.Signature_ALG_ECDSA_SHA; public class ECTesterReader { private CardMngr cardManager; private OutputLogger logger; - private TestWriter testWriter; private ResponseWriter respWriter; - private EC_Store dataStore; private Config cfg; private Options opts = new Options(); @@ -100,10 +97,9 @@ public class ECTesterReader { return; } - dataStore = new EC_Store(); //if list, print and quit if (cli.hasOption("list-named")) { - CLITools.listNamed(dataStore, cli.getOptionValue("list-named")); + CLITools.listNamed(EC_Store.getInstance(), cli.getOptionValue("list-named")); return; } @@ -126,22 +122,7 @@ public class ECTesterReader { // Setup logger, testWriter and respWriter logger = new OutputLogger(true, cfg.log); - if (cfg.format == null) { - testWriter = new TextTestWriter(logger.getPrintStream()); - } else { - switch (cfg.format) { - case "text": - testWriter = new TextTestWriter(logger.getPrintStream()); - break; - case "xml": - testWriter = new XMLTestWriter(logger.getOutputStream()); - break; - case "yaml": - case "yml": - testWriter = new YAMLTestWriter(logger.getPrintStream()); - break; - } - } + respWriter = new ResponseWriter(logger.getPrintStream()); //do action @@ -363,9 +344,9 @@ public class ECTesterReader { private void generate() throws CardException, IOException { byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - Response allocate = new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send(); - respWriter.outputResponse(allocate); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); + Response allocate = new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send(); + respWriter.outputResponse(allocate); + Command curve = Command.prepareCurve(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); FileWriter keysFile = new FileWriter(cfg.output); keysFile.write("index;time;pubW;privS\n"); @@ -414,15 +395,33 @@ public class ECTesterReader { * @throws CardException if APDU transmission fails * @throws IOException if an IO error occurs when writing to key file. */ - private void test() throws IOException, TestException { + private void test() throws IOException, TestException, ParserConfigurationException { + TestWriter writer = null; + if (cfg.format == null) { + writer = new TextTestWriter(logger.getPrintStream()); + } else { + switch (cfg.format) { + case "text": + writer = new TextTestWriter(logger.getPrintStream()); + break; + case "xml": + writer = new XMLTestWriter(logger.getOutputStream()); + break; + case "yaml": + case "yml": + writer = new YAMLTestWriter(logger.getPrintStream()); + break; + } + } + CardTestSuite suite; switch (cfg.testSuite) { case "default": - suite = new CardDefaultSuite(dataStore, cfg); + suite = new CardDefaultSuite(writer, cfg, cardManager); break; case "test-vectors": - suite = new CardTestVectorSuite(dataStore, cfg); + suite = new CardTestVectorSuite(writer, cfg, cardManager); break; default: // These run are dangerous, prompt before them. @@ -437,17 +436,15 @@ public class ECTesterReader { } in.close(); } - - switch (cfg.testSuite) { case "wrong": - suite = new CardWrongCurvesSuite(dataStore, cfg); + suite = new CardWrongCurvesSuite(writer, cfg, cardManager); break; case "composite": - suite = new CardCompositeCurvesSuite(dataStore, cfg); + suite = new CardCompositeCurvesSuite(writer, cfg, cardManager); break; case "invalid": - suite = new CardInvalidCurvesSuite(dataStore, cfg); + suite = new CardInvalidCurvesSuite(writer, cfg, cardManager); break; default: System.err.println("Unknown test suite."); @@ -456,9 +453,7 @@ public class ECTesterReader { break; } - TestRunner runner = new TestRunner(suite, testWriter); - suite.setup(cardManager); - runner.run(); + suite.run(); } /** @@ -472,7 +467,7 @@ public class ECTesterReader { List<Response> prepare = new LinkedList<>(); prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.ECKAType).send()); // Prepare KeyAgreement or required type prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass).send()); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass); + Command curve = Command.prepareCurve(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass); if (curve != null) prepare.add(curve.send()); @@ -486,7 +481,7 @@ public class ECTesterReader { List<Command> generate = new LinkedList<>(); generate.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH)); if (cfg.anyPublicKey || cfg.anyPrivateKey || cfg.anyKey) { - generate.add(Command.prepareKey(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_REMOTE)); + generate.add(Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_REMOTE)); } FileWriter out = null; @@ -554,7 +549,7 @@ public class ECTesterReader { Command generate; if (cfg.anyKeypart) { - generate = Command.prepareKey(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL); + generate = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_LOCAL); } else { generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL); } @@ -563,7 +558,7 @@ public class ECTesterReader { List<Response> prepare = new LinkedList<>(); prepare.add(new Command.AllocateSignature(cardManager, cfg.ECDSAType).send()); prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send()); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); + Command curve = Command.prepareCurve(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); if (curve != null) prepare.add(curve.send()); @@ -620,7 +615,7 @@ public class ECTesterReader { public static class Config { //Options - public int bits; + public short bits; public boolean all; public boolean primeField = false; public boolean binaryField = false; @@ -670,7 +665,7 @@ public class ECTesterReader { * @return whether the options are valid. */ boolean readOptions(CommandLine cli) { - bits = Integer.parseInt(cli.getOptionValue("bit-size", "0")); + bits = Short.parseShort(cli.getOptionValue("bit-size", "0")); all = cli.hasOption("all"); primeField = cli.hasOption("fp"); binaryField = cli.hasOption("f2m"); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index 2c2ba26..a53806c 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -2,13 +2,13 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.common.test.BaseRunnable; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; import javacard.security.KeyPair; import java.util.Map; @@ -20,34 +20,31 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; */ public class CardCompositeCurvesSuite extends CardTestSuite { - public CardCompositeCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "composite", "The composite suite run ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); + public CardCompositeCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "composite", "The composite suite run ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); } @Override - public void setup(CardMngr cardManager) { + protected void runTests() throws Exception { /* Do the default run 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<String, EC_Key> keys = dataStore.getObjects(EC_Key.class, "composite"); + Map<String, EC_Key> keys = EC_Store.getInstance().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; - } + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); 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)) { - run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - run.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); - run.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); - Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); - run.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); + doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); + doTest(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); + new Command.Cleanup(this.card).send(); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java index 7e7adbb..9de741c 100644 --- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -2,15 +2,15 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.common.test.BaseRunnable; -import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.util.CardUtil; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; import javacard.security.KeyPair; -import java.io.IOException; - import static cz.crcs.ectester.common.test.Result.ExpectedValue; /** @@ -18,53 +18,46 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; */ public class CardDefaultSuite extends CardTestSuite { - public CardDefaultSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "default", "The default test suite run basic support of ECDH and ECDSA."); + public CardDefaultSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "default", "The default test suite run basic support of ECDH and ECDSA."); } @Override - public void setup(CardMngr cardManager) throws IOException { - //run.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY)); - if (cfg.namedCurve != null) { - String desc = "Default run over the " + cfg.namedCurve + " curve category."; - if (cfg.primeField) { - run.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); - } - if (cfg.binaryField) { - run.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); + protected void runTests() throws Exception { + if (cfg.primeField) { + runDefault(KeyPair.ALG_EC_FP); + } + if (cfg.binaryField) { + runDefault(KeyPair.ALG_EC_F2M); + } + } + + private void runDefault(byte field) throws Exception { + for (short keyLength : EC_Consts.FP_SIZES) { + Test key = doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS)); + if (!key.ok()) { + continue; } - } 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); - } + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.getCurve(keyLength, field), EC_Consts.PARAMETERS_DOMAIN_FP, null), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); + for (byte kaType : EC_Consts.KA_TYPES) { + Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS); + allocate.run(); + if (allocate.ok()) { + Test ka = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, kaType), ExpectedValue.SUCCESS); + ka.run(); + Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, kaType), ExpectedValue.SUCCESS); + kaCompressed.run(); + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Test of the " + CardUtil.getKATypeString(kaType) + " KeyAgreement.", allocate, ka, kaCompressed)); } - 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); + } + for (byte sigType : EC_Consts.SIG_TYPES) { + Test allocate = doTest(CommandTest.expect(new Command.AllocateSignature(this.card, sigType), ExpectedValue.SUCCESS)); + if (allocate.ok()) { + doTest(CommandTest.expect(new Command.ECDSA(this.card, ECTesterApplet.KEYPAIR_LOCAL, sigType, ECTesterApplet.EXPORT_FALSE, null), ExpectedValue.SUCCESS)); } } } } - - private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); - if (curve != null) - run.add(CommandTest.expect(curve, ExpectedValue.SUCCESS)); - run.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default run.")); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); - } } diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index 3c0795b..0572a66 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -2,18 +2,17 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.common.test.BaseRunnable; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; import javacard.security.KeyPair; -import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -26,22 +25,19 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; */ public class CardInvalidCurvesSuite extends CardTestSuite { - public CardInvalidCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "invalid", "The invalid curve suite run whether the card rejects points outside of the curve during ECDH."); + public CardInvalidCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "invalid", "The invalid curve suite run whether the card rejects points outside of the curve during ECDH."); } @Override - public void setup(CardMngr cardManager) throws IOException { + protected void runTests() throws Exception { /* Set original curves (secg/nist/brainpool). Generate local. * Try ECDH with invalid public keys of increasing (or decreasing) order. */ - Map<String, EC_Key.Public> pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + Map<String, EC_Key.Public> pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "invalid"); Map<EC_Curve, List<EC_Key.Public>> 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; - } + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); if (curve.getBits() != cfg.bits && !cfg.all) { continue; } @@ -56,16 +52,16 @@ public class CardInvalidCurvesSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List<EC_Key.Public> keys = e.getValue(); - run.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - run.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); - run.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); List<Test> ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); - ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.")); } - run.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); + new Command.Cleanup(this.card).send(); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java index 7035ca2..e12a588 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java @@ -3,14 +3,16 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.test.*; -import cz.crcs.ectester.common.test.Runnable; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; -import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -24,14 +26,14 @@ import static cz.crcs.ectester.common.test.Result.Value; */ public abstract class CardTestSuite extends TestSuite { ECTesterReader.Config cfg; + CardMngr card; - CardTestSuite(EC_Store dataStore, ECTesterReader.Config cfg, String name, String description) { - super(dataStore, name, description); + CardTestSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager, String name, String description) { + super(writer, name, description); + this.card = cardManager; this.cfg = cfg; } - public abstract void setup(CardMngr cardManager) throws IOException; - /** * @param cardManager cardManager to send APDU through * @param generateExpected expected result of the Generate command @@ -98,21 +100,20 @@ public abstract class CardTestSuite extends TestSuite { * @param description compound test description * @return run to run */ - List<Runnable> defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { - List<Runnable> tests = new LinkedList<>(); - Map<String, EC_Curve> curves = dataStore.getObjects(EC_Curve.class, category); + List<Test> defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { + Map<String, EC_Curve> curves = EC_Store.getInstance().getObjects(EC_Curve.class, category); if (curves == null) - return tests; + return null; for (Map.Entry<String, EC_Curve> entry : curves.entrySet()) { EC_Curve curve = entry.getValue(); if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); - tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); + //tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); + //tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); + //tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); + //run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); } } - return tests; + return null; } } diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java index 025cbe0..73c6621 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -3,6 +3,7 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.*; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.*; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.data.EC_Store; @@ -25,46 +26,42 @@ import static cz.crcs.ectester.common.test.Result.Value; */ public class CardTestVectorSuite extends CardTestSuite { - public CardTestVectorSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "test", "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); + public CardTestVectorSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "test", "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); } @Override - public void setup(CardMngr cardManager) throws IOException { + protected void runTests() throws Exception { /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. * Do ECDH both ways, export and verify that the result is correct. */ - Map<String, EC_KAResult> results = dataStore.getObjects(EC_KAResult.class, "test"); + Map<String, EC_KAResult> results = EC_Store.getInstance().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; - } + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, result.getCurve()); 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()); + EC_Params onekey = EC_Store.getInstance().getObject(EC_Keypair.class, result.getOneKey()); if (onekey == null) { - onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); + onekey = EC_Store.getInstance().getObject(EC_Key.Private.class, result.getOneKey()); } - EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); + EC_Params otherkey = EC_Store.getInstance().getObject(EC_Keypair.class, result.getOtherKey()); if (otherkey == null) { - otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); + otherkey = EC_Store.getInstance().getObject(EC_Key.Public.class, result.getOtherKey()); } if (onekey == null || otherkey == null) { throw new IOException("Test vector keys couldn't be located."); } List<Test> testVector = new LinkedList<>(); - testVector.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); - //run.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback<CommandTestable>() { + testVector.add(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback<CommandTestable>() { @Override public Result apply(CommandTestable testable) { Response.ECDH dh = (Response.ECDH) testable.getResponse(); @@ -74,13 +71,13 @@ public class CardTestVectorSuite extends CardTestSuite { return new Result(Value.FAILURE, "ECDH response did not contain the derived secret."); if (!ByteUtil.compareBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength())) { int firstDiff = ByteUtil.diffBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength()); - return new Result(Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); + return new Result(Value.FAILURE, "ECDH derived secret does not match the test-vector, first difference was at byte " + String.valueOf(firstDiff) + "."); } return new Result(Value.SUCCESS); } })); - run.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - run.add(new BaseRunnable(() -> new Command.Cleanup(cardManager))); + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + new Command.Cleanup(this.card).send(); } } } diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 8c21aef..3a350c2 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -1,34 +1,58 @@ package cz.crcs.ectester.reader.test; +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; +import cz.crcs.ectester.reader.command.Command; import javacard.security.KeyPair; -import java.io.IOException; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; +import java.util.Map; /** * @author Jan Jancar johny@neuromancer.sk */ public class CardWrongCurvesSuite extends CardTestSuite { - public CardWrongCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "wrong", "The wrong curve suite run whether the card rejects domain parameters which are not curves."); + public CardWrongCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "wrong", "The wrong curve suite run whether the card rejects domain parameters which are not curves."); } @Override - public void setup(CardMngr cardManager) throws IOException { + protected void runTests() throws Exception { /* Just do the default run on the wrong curves. * These should generally fail, the curves aren't curves. */ - String desc = "Default run over wrong curve params."; - if (cfg.primeField) { - run.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); - } - if (cfg.binaryField) { - run.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); + Map<String, EC_Curve> curves = EC_Store.getInstance().getObjects(EC_Curve.class, "wrong"); + for (Map.Entry<String, EC_Curve> e : curves.entrySet()) { + EC_Curve curve = e.getValue(); + 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; + } + Test key = doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); + if (!key.ok()) { + continue; + } + Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS)); + Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.SUCCESS)); + doTest(CompoundTest.any(Result.ExpectedValue.FAILURE, "Set wrong curve and generate keypairs, should fail." ,set, generate)); + + for (byte kaType : EC_Consts.KA_TYPES) { + Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS)); + if (allocate.ok()) { + Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, kaType), Result.ExpectedValue.FAILURE)); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Allocate and perform KA, should fail.", allocate, ka)); + } + } } } } diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index b1b71a5..f5361c3 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -4,7 +4,6 @@ import cz.crcs.ectester.common.cli.*; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestException; -import cz.crcs.ectester.common.test.TestRunner; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.common.util.ECUtil; import cz.crcs.ectester.data.EC_Store; @@ -44,7 +43,6 @@ import java.util.stream.Collectors; */ public class ECTesterStandalone { private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib()}; - private EC_Store dataStore; private Config cfg; private Options opts = new Options(); @@ -76,12 +74,11 @@ public class ECTesterStandalone { if (!cfg.readOptions(cli)) { return; } - dataStore = new EC_Store(); if (cli.isNext("list-libs")) { listLibraries(); } else if (cli.isNext("list-data")) { - CLITools.listNamed(dataStore, cli.getNext().getArg(0)); + CLITools.listNamed(EC_Store.getInstance(), cli.getNext().getArg(0)); } else if (cli.isNext("ecdh")) { ecdh(); } else if (cli.isNext("ecdsa")) { @@ -238,7 +235,7 @@ public class ECTesterStandalone { kpg.initialize(bits); } else if (cli.hasOption("ecdh.named-curve")) { String curveName = cli.getOptionValue("ecdh.named-curve"); - EC_Curve curve = dataStore.getObject(EC_Curve.class, curveName); + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); if (curve == null) { System.err.println("Curve not found: " + curveName); return; @@ -324,7 +321,7 @@ public class ECTesterStandalone { kpg.initialize(bits); } else if (cli.hasOption("ecdsa.named-curve")) { String curveName = cli.getOptionValue("ecdsa.named-curve"); - EC_Curve curve = dataStore.getObject(EC_Curve.class, curveName); + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); if (curve == null) { System.err.println("Curve not found: " + curveName); return; @@ -386,7 +383,7 @@ public class ECTesterStandalone { kpg.initialize(bits); } else if (cli.hasOption("generate.named-curve")) { String curveName = cli.getOptionValue("generate.named-curve"); - EC_Curve curve = dataStore.getObject(EC_Curve.class, curveName); + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); if (curve == null) { System.err.println("Curve not found: " + curveName); return; @@ -429,10 +426,8 @@ public class ECTesterStandalone { break; } - StandaloneTestSuite suite = new StandaloneDefaultSuite(dataStore, cfg, cli); - TestRunner runner = new TestRunner(suite, writer); - suite.setup(); - runner.run(); + StandaloneTestSuite suite = new StandaloneDefaultSuite(writer, cfg, cli); + suite.run(); } /** diff --git a/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java b/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java index b24244e..42d2e54 100644 --- a/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java +++ b/src/cz/crcs/ectester/standalone/test/StandaloneDefaultSuite.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.standalone.test; import cz.crcs.ectester.common.cli.TreeCommandLine; import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.ECTesterStandalone; @@ -11,7 +12,6 @@ import cz.crcs.ectester.standalone.consts.SignatureIdent; import javax.crypto.KeyAgreement; import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.spec.ECParameterSpec; @@ -20,12 +20,12 @@ import java.security.spec.ECParameterSpec; */ public class StandaloneDefaultSuite extends StandaloneTestSuite { - public StandaloneDefaultSuite(EC_Store dataStore, ECTesterStandalone.Config cfg, TreeCommandLine cli) { - super(dataStore, cfg, cli, "default", "The default test suite run basic support of ECDH and ECDSA."); + public StandaloneDefaultSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) { + super(writer, cfg, cli, "default", "The default test suite run basic support of ECDH and ECDSA."); } @Override - public void setup() throws NoSuchAlgorithmException { + protected void runTests() throws Exception { String kpgAlgo = cli.getOptionValue("test.kpg-type", "EC"); String kaAlgo = cli.getOptionValue("test.ka-type"); String sigAlgo = cli.getOptionValue("test.sig-type"); @@ -44,7 +44,7 @@ public class StandaloneDefaultSuite extends StandaloneTestSuite { kgtOther = new KeyGeneratorTestable(kpg, bits); } else if (cli.hasOption("test.named-curve")) { String curveName = cli.getOptionValue("test.named-curve"); - EC_Curve curve = dataStore.getObject(EC_Curve.class, curveName); + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); if (curve == null) { System.err.println("Curve not found: " + curveName); return; @@ -57,19 +57,19 @@ public class StandaloneDefaultSuite extends StandaloneTestSuite { kgtOther = new KeyGeneratorTestable(kpg); } - run.add(KeyGeneratorTest.expect(kgtOne, Result.ExpectedValue.SUCCESS)); - run.add(KeyGeneratorTest.expect(kgtOther, Result.ExpectedValue.SUCCESS)); + doTest(KeyGeneratorTest.expect(kgtOne, Result.ExpectedValue.SUCCESS)); + doTest(KeyGeneratorTest.expect(kgtOther, Result.ExpectedValue.SUCCESS)); for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { if (kaAlgo == null || kaIdent.contains(kaAlgo)) { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - run.add(KeyAgreementTest.expect(new KeyAgreementTestable(ka, kgtOne, kgtOther, spec), Result.ExpectedValue.SUCCESS)); + doTest(KeyAgreementTest.expect(new KeyAgreementTestable(ka, kgtOne, kgtOther, spec), Result.ExpectedValue.SUCCESS)); } } for (SignatureIdent sigIdent : cfg.selected.getSigs()) { if (sigAlgo == null || sigIdent.contains(sigAlgo)) { Signature sig = sigIdent.getInstance(cfg.selected.getProvider()); - run.add(SignatureTest.expect(new SignatureTestable(sig, kgtOne, null), Result.ExpectedValue.SUCCESS)); + doTest(SignatureTest.expect(new SignatureTestable(sig, kgtOne, null), Result.ExpectedValue.SUCCESS)); } } } diff --git a/src/cz/crcs/ectester/standalone/test/StandaloneTestSuite.java b/src/cz/crcs/ectester/standalone/test/StandaloneTestSuite.java index 5682cd5..ad404c8 100644 --- a/src/cz/crcs/ectester/standalone/test/StandaloneTestSuite.java +++ b/src/cz/crcs/ectester/standalone/test/StandaloneTestSuite.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.standalone.test; import cz.crcs.ectester.common.cli.TreeCommandLine; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.ECTesterStandalone; @@ -14,11 +15,9 @@ public abstract class StandaloneTestSuite extends TestSuite { TreeCommandLine cli; ECTesterStandalone.Config cfg; - public StandaloneTestSuite(EC_Store dataStore, ECTesterStandalone.Config cfg, TreeCommandLine cli, String name, String description) { - super(dataStore, name, description); + public StandaloneTestSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli, String name, String description) { + super(writer, name, description); this.cfg = cfg; this.cli = cli; } - - public abstract void setup() throws NoSuchAlgorithmException; } |
