From 9e615b101398bd4c8e2678bf86337e2756a8ee7a Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 12 Nov 2017 23:39:35 +0100 Subject: Implement collecting of supported KeyAgreement and Signature objects. --- .../ectester/standalone/ECTesterStandalone.java | 26 ++++++- src/cz/crcs/ectester/standalone/consts/Ident.java | 41 +++++++++++ .../standalone/consts/KeyAgreementIdent.java | 53 ++++++++++++++ .../ectester/standalone/consts/SignatureIdent.java | 77 ++++++++++++++++++++ .../ectester/standalone/libs/BouncyCastleLib.java | 19 ++--- .../crcs/ectester/standalone/libs/CECLibrary.java | 31 ++++++++ .../crcs/ectester/standalone/libs/ECLibrary.java | 21 ++++++ .../ectester/standalone/libs/JavaECLibrary.java | 85 ++++++++++++++++++++++ src/cz/crcs/ectester/standalone/libs/SunECLib.java | 14 ++++ 9 files changed, 353 insertions(+), 14 deletions(-) create mode 100644 src/cz/crcs/ectester/standalone/consts/Ident.java create mode 100644 src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java create mode 100644 src/cz/crcs/ectester/standalone/consts/SignatureIdent.java create mode 100644 src/cz/crcs/ectester/standalone/libs/CECLibrary.java create mode 100644 src/cz/crcs/ectester/standalone/libs/ECLibrary.java create mode 100644 src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java create mode 100644 src/cz/crcs/ectester/standalone/libs/SunECLib.java (limited to 'src') diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index d2cbce1..47b7121 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -1,12 +1,15 @@ package cz.crcs.ectester.standalone; -import cz.crcs.ectester.common.Util; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.standalone.libs.BouncyCastleLib; +import cz.crcs.ectester.standalone.libs.ECLibrary; +import cz.crcs.ectester.standalone.libs.SunECLib; import org.apache.commons.cli.*; import java.io.IOException; +import java.util.Arrays; /** * Standalone part of ECTester, a tool for testing Elliptic curve implementations in software libraries. @@ -16,6 +19,7 @@ import java.io.IOException; */ public class ECTesterStandalone { + private ECLibrary[] libs = new ECLibrary[]{new SunECLib(), new BouncyCastleLib()}; private EC_Store dataStore; private Config cfg; @@ -40,9 +44,17 @@ public class ECTesterStandalone { cfg = new Config(); dataStore = new EC_Store(); + for (ECLibrary lib : libs) { + lib.initialize(); + lib.getECKAs(); + lib.getECSigs(); + } + System.out.println(Arrays.toString(libs)); if (cli.hasOption("generate")) { generate(); + } else if (cli.hasOption("libs")) { + listLibraries(); } } catch (ParseException | IOException ex) { @@ -56,6 +68,7 @@ public class ECTesterStandalone { actions.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build()); actions.addOption(Option.builder("h").longOpt("help").desc("Print help.").build()); actions.addOption(Option.builder("g").longOpt("generate").desc("Generate [amount] of EC keys.").hasArg().argName("amount").optionalArg(true).build()); + actions.addOption(Option.builder("ls").longOpt("libs").desc("List supported libraries.").build()); opts.addOptionGroup(actions); CommandLineParser parser = new DefaultParser(); @@ -88,6 +101,17 @@ public class ECTesterStandalone { } + /** + * + */ + private void listLibraries() { + for (ECLibrary lib : libs) { + if (lib.isInitialized()) { + System.out.println(lib.name()); + } + } + } + public static void main(String[] args) { ECTesterStandalone app = new ECTesterStandalone(); app.run(args); diff --git a/src/cz/crcs/ectester/standalone/consts/Ident.java b/src/cz/crcs/ectester/standalone/consts/Ident.java new file mode 100644 index 0000000..3228c37 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/consts/Ident.java @@ -0,0 +1,41 @@ +package cz.crcs.ectester.standalone.consts; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; +import java.util.TreeSet; + +public abstract class Ident { + private Set idents; + + public Ident(String... names) { + this.idents = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + this.idents.addAll(Arrays.asList(names)); + } + + public Set getIdents() { + return Collections.unmodifiableSet(idents); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Ident)) { + return false; + } + Ident other = (Ident) obj; + return idents.equals(other.getIdents()); + } + + @Override + public int hashCode() { + return idents.hashCode() + 37; + } + + @Override + public String toString() { + return "(" + String.join("|", idents) + ")"; + } +} diff --git a/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java b/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java new file mode 100644 index 0000000..9dc9797 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java @@ -0,0 +1,53 @@ +package cz.crcs.ectester.standalone.consts; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class KeyAgreementIdent extends Ident { + private static final List ALL = new LinkedList<>(); + + static { + //https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html + // Basic ECDH and ECDHC (plain/raw) + ALL.add(new KeyAgreementIdent("ECDH")); + ALL.add(new KeyAgreementIdent("ECDHC", "ECCDH")); + // ECDH and ECDHC with SHA as KDF, OIDs from RFC 3278 + ALL.add(new KeyAgreementIdent("ECDHwithSHA1KDF", "1.3.133.16.840.63.0.2")); + ALL.add(new KeyAgreementIdent("ECCDHwithSHA1KDF", "1.3.133.16.840.63.0.3")); + ALL.add(new KeyAgreementIdent("ECDHwithSHA224KDF", "1.3.132.1.11.0")); + ALL.add(new KeyAgreementIdent("ECCDHwithSHA224KDF", "1.3.132.1.14.0")); + ALL.add(new KeyAgreementIdent("ECDHwithSHA256KDF", "1.3.132.1.11.1")); + ALL.add(new KeyAgreementIdent("ECCDHwithSHA256KDF", "1.3.132.1.14.1")); + ALL.add(new KeyAgreementIdent("ECDHwithSHA384KDF", "1.3.132.1.11.2")); + ALL.add(new KeyAgreementIdent("ECCDHwithSHA384KDF", "1.3.132.1.14.2")); + ALL.add(new KeyAgreementIdent("ECDHwithSHA512KDF", "1.3.132.1.11.3")); + ALL.add(new KeyAgreementIdent("ECCDHwithSHA512KDF", "1.3.132.1.14.3")); + // ECMQV + ALL.add(new KeyAgreementIdent("ECMQV")); + ALL.add(new KeyAgreementIdent("ECMQVwithSHA1CKDF", "1.3.133.16.840.63.0.16")); + ALL.add(new KeyAgreementIdent("ECMQVwithSHA224CKDF", "1.3.132.1.15.0")); + ALL.add(new KeyAgreementIdent("ECMQVwithSHA256CKDF", "1.3.132.1.15.1")); + ALL.add(new KeyAgreementIdent("ECMQVwithSHA384CKDF", "1.3.132.1.15.2")); + ALL.add(new KeyAgreementIdent("ECMQVwithSHA512CKDF", "1.3.132.1.15.3")); + // ECVKO + ALL.add(new KeyAgreementIdent("ECVKO", "ECGOST3410", "1.2.643.2.2.19", "GOST-3410-2001", "1.2.643.2.2.96")); + ALL.add(new KeyAgreementIdent("ECVKO256", "ECGOST3410-2012-256", "1.2.643.7.1.1.6.1", "1.2.643.7.1.1.1.1")); + ALL.add(new KeyAgreementIdent("ECVKO512", "ECGOST3410-2012-512", "1.2.643.7.1.1.6.2", "1.2.643.7.1.1.1.2")); + } + + public static KeyAgreementIdent get(String ident) { + for (KeyAgreementIdent ka : ALL) { + if (ka.getIdents().contains(ident)) { + return ka; + } + } + return null; + } + + private KeyAgreementIdent(String... names) { + super(names); + } +} diff --git a/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java b/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java new file mode 100644 index 0000000..b41e9e4 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java @@ -0,0 +1,77 @@ +package cz.crcs.ectester.standalone.consts; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class SignatureIdent extends Ident { + private static final List ALL = new LinkedList<>(); + + static { + //https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html + // ECDSA + ALL.add(new SignatureIdent("ECDSA", "SHA1withECDSA", "ECDSAwithSHA1", "1.2.840.10045.4.1", "1.3.36.3.3.2.1")); + ALL.add(new SignatureIdent("NONEwithECDSA")); + ALL.add(new SignatureIdent("SHA224withECDSA", "SHA224/ECDSA", "1.2.840.10045.4.3.1")); + ALL.add(new SignatureIdent("SHA256withECDSA", "SHA256/ECDSA", "1.2.840.10045.4.3.2")); + ALL.add(new SignatureIdent("SHA384withECDSA", "SHA384/ECDSA", "1.2.840.10045.4.3.3")); + ALL.add(new SignatureIdent("SHA512withECDSA", "SHA512/ECDSA", "1.2.840.10045.4.3.4")); + ALL.add(new SignatureIdent("SHA3-224withECDSA", "SHA3-224/ECDSA", "2.16.840.1.101.3.4.3.9")); + ALL.add(new SignatureIdent("SHA3-256withECDSA", "SHA3-256/ECDSA", "2.16.840.1.101.3.4.3.10")); + ALL.add(new SignatureIdent("SHA3-384withECDSA", "SHA3-384/ECDSA", "2.16.840.1.101.3.4.3.11")); + ALL.add(new SignatureIdent("SHA3-512withECDSA", "SHA3-512/ECDSA", "2.16.840.1.101.3.4.3.12")); + ALL.add(new SignatureIdent("RIPEMD160withECDSA", "RIPEMD160/ECDSA", "1.3.36.3.3.2.2")); + // ECNR + ALL.add(new SignatureIdent("SHA1withECNR")); + ALL.add(new SignatureIdent("SHA224withECNR")); + ALL.add(new SignatureIdent("SHA256withECNR")); + ALL.add(new SignatureIdent("SHA512withECNR")); + // CVC-ECDSA + ALL.add(new SignatureIdent("SHA1withCVC-ECDSA", "SHA1/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.1")); + ALL.add(new SignatureIdent("SHA224withCVC-ECDSA", "SHA224/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.2")); + ALL.add(new SignatureIdent("SHA256withCVC-ECDSA", "SHA256/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.3")); + ALL.add(new SignatureIdent("SHA384withCVC-ECDSA", "SHA384/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.4")); + ALL.add(new SignatureIdent("SHA512withCVC-ECDSA", "SHA512/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.5")); + // PLAIN-ECDSA + ALL.add(new SignatureIdent("SHA1withPLAIN-ECDSA", "SHA1/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.1")); + ALL.add(new SignatureIdent("SHA224withPLAIN-ECDSA", "SHA224/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.2")); + ALL.add(new SignatureIdent("SHA256withPLAIN-ECDSA", "SHA256/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.3")); + ALL.add(new SignatureIdent("SHA384withPLAIN-ECDSA", "SHA384/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.4")); + ALL.add(new SignatureIdent("SHA512withPLAIN-ECDSA", "SHA512/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.5")); + ALL.add(new SignatureIdent("RIPEMD160withPLAIN-ECDSA", "RIPEMD160/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.6")); + // ECGOST + ALL.add(new SignatureIdent("ECGOST3410", "ECGOST-3410", "GOST-3410-2001")); + ALL.add(new SignatureIdent("GOST3411withECGOST3410", "GOST3411/ECGOST3410", "1.2.643.2.2.3")); + ALL.add(new SignatureIdent("ECGOST3410-2012-256", "GOST-3410-2012-256")); + ALL.add(new SignatureIdent("GOST3411-2012-256withECGOST3410-2012-256", "GOST3411-2012-256/ECGOST3410-2012-2560", "1.2.643.7.1.1.3.2")); + ALL.add(new SignatureIdent("ECGOST3410-2012-512", "GOST-3410-2012-512")); + ALL.add(new SignatureIdent("GOST3411-2012-512withECGOST3410-2012-512", "GOST3411-2012-512/ECGOST3410-2012-5120", "1.2.643.7.1.1.3.3")); + ALL.add(new SignatureIdent("SM3withSM2")); + // ECDDSA + ALL.add(new SignatureIdent("ECDDSA", "DETECDSA", "ECDETDSA")); + ALL.add(new SignatureIdent("SHA1withECDDSA", "SHA1withDETECDSA")); + ALL.add(new SignatureIdent("SHA224withECDDSA", "SHA224withDETECDSA")); + ALL.add(new SignatureIdent("SHA256withECDDSA", "SHA256withDETECDSA")); + ALL.add(new SignatureIdent("SHA384withECDDSA", "SHA384withDETECDSA")); + ALL.add(new SignatureIdent("SHA512withECDDSA", "SHA512withDETECDSA")); + ALL.add(new SignatureIdent("SHA3-224withECDDSA", "SHA3-224withDETECDSA")); + ALL.add(new SignatureIdent("SHA3-256withECDDSA", "SHA3-256withDETECDSA")); + ALL.add(new SignatureIdent("SHA3-384withECDDSA", "SHA3-384withDETECDSA")); + ALL.add(new SignatureIdent("SHA3-512withECDDSA", "SHA3-512withDETECDSA")); + } + + public static SignatureIdent get(String ident) { + for (SignatureIdent sig : ALL) { + if (sig.getIdents().contains(ident)) { + return sig; + } + } + return null; + } + + private SignatureIdent(String... names) { + super(names); + } +} diff --git a/src/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java b/src/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java index 78da737..73cd197 100644 --- a/src/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java +++ b/src/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java @@ -1,21 +1,14 @@ package cz.crcs.ectester.standalone.libs; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import java.security.Security; +import org.bouncycastle.jce.provider.BouncyCastleProvider; -public class BouncyCastleLib { +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class BouncyCastleLib extends JavaECLibrary { public BouncyCastleLib() { - - } - - public boolean setUp() { - try { - Security.addProvider(new BouncyCastleProvider()); - } catch (NullPointerException | SecurityException ignored) { - return false; - } - return true; + super(new BouncyCastleProvider()); } } diff --git a/src/cz/crcs/ectester/standalone/libs/CECLibrary.java b/src/cz/crcs/ectester/standalone/libs/CECLibrary.java new file mode 100644 index 0000000..82a4555 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/libs/CECLibrary.java @@ -0,0 +1,31 @@ +package cz.crcs.ectester.standalone.libs; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class CECLibrary implements ECLibrary { + + private String resourcePath; + private String libname; + + public CECLibrary(String resourcePath, String libname) { + this.resourcePath = resourcePath; + this.libname = libname; + } + + @Override + public boolean initialize() { + // load the library here. + return false; + } + + @Override + public String name() { + return libname; + } + + @Override + public String toString() { + return name(); + } +} diff --git a/src/cz/crcs/ectester/standalone/libs/ECLibrary.java b/src/cz/crcs/ectester/standalone/libs/ECLibrary.java new file mode 100644 index 0000000..b2792bd --- /dev/null +++ b/src/cz/crcs/ectester/standalone/libs/ECLibrary.java @@ -0,0 +1,21 @@ +package cz.crcs.ectester.standalone.libs; + +import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; +import cz.crcs.ectester.standalone.consts.SignatureIdent; + +import java.util.Set; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public interface ECLibrary { + boolean initialize(); + + boolean isInitialized(); + + Set getECKAs(); + + Set getECSigs(); + + String name(); +} diff --git a/src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java b/src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java new file mode 100644 index 0000000..f8848da --- /dev/null +++ b/src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java @@ -0,0 +1,85 @@ +package cz.crcs.ectester.standalone.libs; + +import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; +import cz.crcs.ectester.standalone.consts.SignatureIdent; + +import java.security.Provider; +import java.security.Security; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class JavaECLibrary implements ECLibrary { + private Provider provider; + private boolean initialized; + + public JavaECLibrary(Provider provider) { + this.provider = provider; + this.initialized = false; + } + + @Override + public boolean initialize() { + try { + int result = Security.addProvider(provider); + if (result == -1) { + provider = Security.getProvider(provider.getName()); + } + initialized = true; + } catch (NullPointerException | SecurityException ignored) { + initialized = false; + } + return initialized; + } + + @Override + public boolean isInitialized() { + return initialized; + } + + @Override + public Set getECKAs() { + Set results = new HashSet<>(); + for (Provider.Service service : provider.getServices()) { + if (service.getType().equals("KeyAgreement")) { + KeyAgreementIdent id = KeyAgreementIdent.get(service.getAlgorithm()); + if (id != null) { + results.add(id); + } + } + } + System.out.println(results); + return results; + } + + @Override + public Set getECSigs() { + Set results = new HashSet<>(); + for (Provider.Service service : provider.getServices()) { + if (service.getType().equals("Signature")) { + SignatureIdent id = SignatureIdent.get(service.getAlgorithm()); + if (id != null) { + results.add(id); + } + } + } + System.out.println(results); + return results; + } + + @Override + public String name() { + return provider.getInfo(); + } + + public Provider getProvider() { + return provider; + } + + @Override + public String toString() { + return name(); + } +} diff --git a/src/cz/crcs/ectester/standalone/libs/SunECLib.java b/src/cz/crcs/ectester/standalone/libs/SunECLib.java new file mode 100644 index 0000000..408908e --- /dev/null +++ b/src/cz/crcs/ectester/standalone/libs/SunECLib.java @@ -0,0 +1,14 @@ +package cz.crcs.ectester.standalone.libs; + +import sun.security.ec.SunEC; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class SunECLib extends JavaECLibrary { + + public SunECLib() { + super(new SunEC()); + } + +} -- cgit v1.2.3-70-g09d2 From cccf2c9c382fa63c68a6c3821d587bc2caa72b05 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 13 Nov 2017 18:03:00 +0100 Subject: Add KeyAgreement/KeyGeneration/Signature tests. Implement KeyAgreementTest. --- src/cz/crcs/ectester/common/test/TestCallback.java | 11 +++ .../ectester/reader/output/TextTestWriter.java | 6 +- .../crcs/ectester/reader/output/XMLTestWriter.java | 6 +- .../ectester/reader/output/YAMLTestWriter.java | 6 +- src/cz/crcs/ectester/reader/test/CommandTest.java | 71 +++++++++++++++++++ .../ectester/reader/test/CompositeCurvesSuite.java | 10 +-- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 8 +-- .../ectester/reader/test/InvalidCurvesSuite.java | 10 +-- src/cz/crcs/ectester/reader/test/SimpleTest.java | 71 ------------------- src/cz/crcs/ectester/reader/test/TestSuite.java | 22 +++--- .../crcs/ectester/reader/test/TestVectorSuite.java | 12 ++-- src/cz/crcs/ectester/standalone/consts/Ident.java | 13 +++- .../standalone/consts/KeyAgreementIdent.java | 11 ++- .../ectester/standalone/consts/SignatureIdent.java | 11 ++- .../ectester/standalone/test/KeyAgreementTest.java | 55 +++++++++++++++ .../standalone/test/KeyAgreementTestable.java | 80 ++++++++++++++++++++++ .../standalone/test/KeyGenerationTest.java | 19 +++++ .../ectester/standalone/test/SignatureTest.java | 19 +++++ 18 files changed, 323 insertions(+), 118 deletions(-) create mode 100644 src/cz/crcs/ectester/common/test/TestCallback.java create mode 100644 src/cz/crcs/ectester/reader/test/CommandTest.java delete mode 100644 src/cz/crcs/ectester/reader/test/SimpleTest.java create mode 100644 src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java create mode 100644 src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java create mode 100644 src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java create mode 100644 src/cz/crcs/ectester/standalone/test/SignatureTest.java (limited to 'src') diff --git a/src/cz/crcs/ectester/common/test/TestCallback.java b/src/cz/crcs/ectester/common/test/TestCallback.java new file mode 100644 index 0000000..488e2f2 --- /dev/null +++ b/src/cz/crcs/ectester/common/test/TestCallback.java @@ -0,0 +1,11 @@ +package cz.crcs.ectester.common.test; + +import java.util.function.Function; + +/** + * + * @param + */ +public abstract class TestCallback implements Function { + +} diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index 07b2a2f..dc285b5 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -2,7 +2,7 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.SimpleTest; +import cz.crcs.ectester.reader.test.CommandTest; import cz.crcs.ectester.reader.test.TestSuite; import java.io.PrintStream; @@ -33,8 +33,8 @@ public class TextTestWriter implements TestWriter { } StringBuilder out = new StringBuilder(); - if (t instanceof SimpleTest) { - SimpleTest test = (SimpleTest) t; + if (t instanceof CommandTest) { + CommandTest test = (CommandTest) t; out.append(test.ok() ? "OK " : "NOK "); out.append("━ "); int width = BASE_WIDTH - (offset + out.length()); diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index 24a308c..0a5155b 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -5,7 +5,7 @@ import cz.crcs.ectester.common.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.SimpleTest; +import cz.crcs.ectester.reader.test.CommandTest; import cz.crcs.ectester.reader.test.TestSuite; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -91,8 +91,8 @@ public class XMLTestWriter implements TestWriter { private Element testElement(Test t) { Element testElem = doc.createElement("test"); - if (t instanceof SimpleTest) { - SimpleTest test = (SimpleTest) t; + if (t instanceof CommandTest) { + CommandTest test = (CommandTest) t; testElem.setAttribute("type", "simple"); testElem.appendChild(commandElement(test.getCommand())); testElem.appendChild(responseElement(test.getResponse())); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index c637a13..84f1eac 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -5,7 +5,7 @@ import cz.crcs.ectester.common.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.SimpleTest; +import cz.crcs.ectester.reader.test.CommandTest; import cz.crcs.ectester.reader.test.TestSuite; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -66,8 +66,8 @@ public class YAMLTestWriter implements TestWriter { private Map testObject(Test t) { Map testObj = new HashMap<>(); - if (t instanceof SimpleTest) { - SimpleTest test = (SimpleTest) t; + if (t instanceof CommandTest) { + CommandTest test = (CommandTest) t; testObj.put("type", "simple"); testObj.put("command", commandObject(test.getCommand())); testObj.put("response", responseObject(test.getResponse())); diff --git a/src/cz/crcs/ectester/reader/test/CommandTest.java b/src/cz/crcs/ectester/reader/test/CommandTest.java new file mode 100644 index 0000000..b7728b6 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CommandTest.java @@ -0,0 +1,71 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestException; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.response.Response; + +import javax.smartcardio.CardException; +import java.util.function.BiFunction; + +/** + * A simple test that runs one Command to get and evaluate one Response + * to get a Result and compare it with the expected one. + */ +public class CommandTest extends Test { + private BiFunction callback; + private Command command; + private Response response; + + public CommandTest(Command command, BiFunction callback) { + this.command = command; + this.callback = callback; + } + + public CommandTest(Command command, Result.ExpectedValue expected, String ok, String nok) { + this(command, (cmd, resp) -> { + Result.Value resultValue = Result.Value.fromExpected(expected, resp.successful(), resp.error()); + return new Result(resultValue, resultValue.ok() ? ok : nok); + }); + } + + public CommandTest(Command command, Result.ExpectedValue expected) { + this(command, expected, null, null); + } + + public Command getCommand() { + return command; + } + + public Response getResponse() { + return response; + } + + @Override + public void run() throws TestException { + if (hasRun) + return; + + try { + response = command.send(); + } catch (CardException e) { + throw new TestException(e); + } + if (callback != null) { + result = callback.apply(command, response); + } else { + if (response.successful()) { + result = new Result(Result.Value.SUCCESS); + } else { + result = new Result(Result.Value.FAILURE); + } + } + hasRun = true; + } + + @Override + public String getDescription() { + return response.getDescription(); + } +} diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index 2e711a2..77df7d6 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -41,12 +41,12 @@ public class CompositeCurvesSuite extends TestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - tests.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); - tests.add(new SimpleTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); + tests.add(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + tests.add(new CommandTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()); - tests.add(new SimpleTest(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); - tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.")); + tests.add(new CommandTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index fb8fdab..0e25312 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -23,7 +23,7 @@ public class DefaultSuite extends TestSuite { @Override public void setup(CardMngr cardManager) throws IOException { - tests.add(new SimpleTest(new Command.Support(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(new Command.Support(cardManager), ExpectedValue.ANY)); if (cfg.namedCurve != null) { String desc = "Default tests over the " + cfg.namedCurve + " curve category."; if (cfg.primeField) { @@ -59,11 +59,11 @@ public class DefaultSuite extends TestSuite { } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) - tests.add(new SimpleTest(curve, ExpectedValue.SUCCESS)); + tests.add(new CommandTest(curve, ExpectedValue.SUCCESS)); tests.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default tests.")); - tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java index 1f71ad5..e4afb5d 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -55,16 +55,16 @@ public class InvalidCurvesSuite extends TestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - tests.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - tests.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); - tests.add(new SimpleTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()); - ecdhTests.add(new SimpleTest(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); + ecdhTests.add(new CommandTest(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); } tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); - tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/SimpleTest.java b/src/cz/crcs/ectester/reader/test/SimpleTest.java deleted file mode 100644 index 067f43e..0000000 --- a/src/cz/crcs/ectester/reader/test/SimpleTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package cz.crcs.ectester.reader.test; - -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestException; -import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.response.Response; - -import javax.smartcardio.CardException; -import java.util.function.BiFunction; - -/** - * A simple test that runs one Command to get and evaluate one Response - * to get a Result and compare it with the expected one. - */ -public class SimpleTest extends Test { - private BiFunction callback; - private Command command; - private Response response; - - public SimpleTest(Command command, BiFunction callback) { - this.command = command; - this.callback = callback; - } - - public SimpleTest(Command command, Result.ExpectedValue expected, String ok, String nok) { - this(command, (cmd, resp) -> { - Result.Value resultValue = Result.Value.fromExpected(expected, resp.successful(), resp.error()); - return new Result(resultValue, resultValue.ok() ? ok : nok); - }); - } - - public SimpleTest(Command command, Result.ExpectedValue expected) { - this(command, expected, null, null); - } - - public Command getCommand() { - return command; - } - - public Response getResponse() { - return response; - } - - @Override - public void run() throws TestException { - if (hasRun) - return; - - try { - response = command.send(); - } catch (CardException e) { - throw new TestException(e); - } - if (callback != null) { - result = callback.apply(command, response); - } else { - if (response.successful()) { - result = new Result(Result.Value.SUCCESS); - } else { - result = new Result(Result.Value.FAILURE); - } - } - hasRun = true; - } - - @Override - public String getDescription() { - return response.getDescription(); - } -} diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index dc8167b..034f579 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -64,14 +64,14 @@ public abstract class TestSuite { Test defaultCurveTests(CardMngr cardManager, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressExpected, ExpectedValue ecdsaExpected, String description) { List tests = new LinkedList<>(); - tests.add(new SimpleTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); - tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); - tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); - tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); - tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); - tests.add(new SimpleTest(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); + tests.add(new CommandTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); + tests.add(new CommandTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new CommandTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new CommandTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new CommandTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new CommandTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new CommandTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new CommandTest(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return CompoundTest.function((testArray) -> { Function shouldHave = (expected) -> { @@ -126,10 +126,10 @@ public abstract class TestSuite { for (Map.Entry entry : curves.entrySet()) { EC_Curve curve = entry.getValue(); if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); - tests.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); + tests.add(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); - tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 3f11a79..77653d1 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -61,12 +61,12 @@ public class TestVectorSuite extends TestSuite { } List testVector = new LinkedList<>(); - testVector.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - testVector.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + testVector.add(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + testVector.add(new CommandTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); - testVector.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); - testVector.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); - testVector.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> { + testVector.add(new CommandTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); + testVector.add(new CommandTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); + testVector.add(new CommandTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> { Response.ECDH dh = (Response.ECDH) response; if (!dh.successful()) return new Result(Value.FAILURE, "ECDH was unsuccessful."); @@ -79,7 +79,7 @@ public class TestVectorSuite extends TestSuite { return new Result(Value.SUCCESS); })); tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/standalone/consts/Ident.java b/src/cz/crcs/ectester/standalone/consts/Ident.java index 3228c37..eaea0e3 100644 --- a/src/cz/crcs/ectester/standalone/consts/Ident.java +++ b/src/cz/crcs/ectester/standalone/consts/Ident.java @@ -6,11 +6,18 @@ import java.util.Set; import java.util.TreeSet; public abstract class Ident { - private Set idents; + Set idents; + String name; - public Ident(String... names) { + public Ident(String name, String... aliases) { + this.name = name; this.idents = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - this.idents.addAll(Arrays.asList(names)); + this.idents.add(name); + this.idents.addAll(Arrays.asList(aliases)); + } + + public String getName() { + return name; } public Set getIdents() { diff --git a/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java b/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java index 9dc9797..22b03a4 100644 --- a/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java +++ b/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java @@ -1,5 +1,8 @@ package cz.crcs.ectester.standalone.consts; +import javax.crypto.KeyAgreement; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; import java.util.LinkedList; import java.util.List; @@ -47,7 +50,11 @@ public class KeyAgreementIdent extends Ident { return null; } - private KeyAgreementIdent(String... names) { - super(names); + private KeyAgreementIdent(String name, String... aliases) { + super(name, aliases); + } + + public KeyAgreement getInstance(Provider provider) throws NoSuchAlgorithmException { + return KeyAgreement.getInstance(name, provider); } } diff --git a/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java b/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java index b41e9e4..dc554e2 100644 --- a/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java +++ b/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java @@ -1,5 +1,8 @@ package cz.crcs.ectester.standalone.consts; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Signature; import java.util.LinkedList; import java.util.List; @@ -71,7 +74,11 @@ public class SignatureIdent extends Ident { return null; } - private SignatureIdent(String... names) { - super(names); + private SignatureIdent(String name, String... aliases) { + super(name, aliases); + } + + public Signature getInstance(Provider provider) throws NoSuchAlgorithmException { + return Signature.getInstance(name, provider); } } diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java new file mode 100644 index 0000000..9c761fa --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java @@ -0,0 +1,55 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestCallback; +import cz.crcs.ectester.common.test.TestException; + +import java.util.Arrays; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class KeyAgreementTest extends Test { + private KeyAgreementTestable ka; + private TestCallback callback; + + private KeyAgreementTest(KeyAgreementTestable ka, TestCallback callback) { + this.ka = ka; + this.callback = callback; + } + + public static KeyAgreementTest match(KeyAgreementTestable ka, byte[] expectedSecret) { + return new KeyAgreementTest(ka, new TestCallback() { + @Override + public Result apply(KeyAgreementTestable ka) { + if (Arrays.equals(ka.getSecret(), expectedSecret)) { + return new Result(Result.Value.SUCCESS); + } else { + return new Result(Result.Value.FAILURE); + } + } + }); + } + + public static KeyAgreementTest expect(KeyAgreementTestable ka, Result.ExpectedValue expected) { + return new KeyAgreementTest(ka, new TestCallback() { + @Override + public Result apply(KeyAgreementTestable keyAgreementTestable) { + return new Result(Result.Value.fromExpected(expected, keyAgreementTestable.ok(), keyAgreementTestable.error())); + } + }); + } + + @Override + public String getDescription() { + return null; + } + + @Override + public void run() throws TestException { + ka.run(); + result = callback.apply(ka); + hasRun = true; + } +} diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java new file mode 100644 index 0000000..51c295c --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java @@ -0,0 +1,80 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.TestException; +import cz.crcs.ectester.common.test.Testable; + +import javax.crypto.KeyAgreement; +import java.security.InvalidKeyException; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class KeyAgreementTestable implements Testable { + private KeyAgreement ka; + private ECPrivateKey privateKey; + private ECPublicKey publicKey; + private byte[] secret; + private boolean hasRun; + private boolean error; + private boolean ok; + + public KeyAgreementTestable(KeyAgreement ka, ECPrivateKey privateKey, ECPublicKey publicKey) { + this.ka = ka; + this.privateKey = privateKey; + this.publicKey = publicKey; + } + + public byte[] getSecret() { + if (!hasRun) { + return null; + } + return secret; + } + + @Override + public boolean hasRun() { + return hasRun; + } + + @Override + public void run() throws TestException { + try { + ka.init(privateKey); + } catch (InvalidKeyException ikex) { + throw new TestException(ikex); + } + + try { + ka.doPhase(publicKey, true); + } catch (InvalidKeyException ikex) { + throw new TestException(ikex); + } catch (IllegalStateException isex) { + error = true; + ok = false; + hasRun = true; + return; + } + + try { + secret = ka.generateSecret(); + } catch (IllegalStateException isex) { + error = true; + ok = false; + hasRun = true; + return; + } + ok = true; + } + + @Override + public boolean ok() { + return ok; + } + + @Override + public boolean error() { + return error; + } +} diff --git a/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java b/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java new file mode 100644 index 0000000..7a96ba1 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java @@ -0,0 +1,19 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestException; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class KeyGenerationTest extends Test { + @Override + public String getDescription() { + return null; + } + + @Override + public void run() throws TestException { + + } +} diff --git a/src/cz/crcs/ectester/standalone/test/SignatureTest.java b/src/cz/crcs/ectester/standalone/test/SignatureTest.java new file mode 100644 index 0000000..2102db0 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/SignatureTest.java @@ -0,0 +1,19 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestException; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class SignatureTest extends Test { + @Override + public String getDescription() { + return null; + } + + @Override + public void run() throws TestException { + + } +} -- cgit v1.2.3-70-g09d2 From 35bdac1fff6e98485d5fbef870d6438fdbbd00c3 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 13 Nov 2017 22:49:41 +0100 Subject: Implement basic lib tests. --- .../ectester/standalone/test/KeyAgreementTest.java | 4 + .../standalone/test/KeyAgreementTestable.java | 5 +- .../standalone/test/KeyGenerationTest.java | 27 +++++- .../standalone/test/KeyGenerationTestable.java | 67 ++++++++++++++ .../ectester/standalone/test/SignatureTest.java | 13 ++- .../standalone/test/SignatureTestable.java | 102 +++++++++++++++++++++ 6 files changed, 213 insertions(+), 5 deletions(-) create mode 100644 src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java create mode 100644 src/cz/crcs/ectester/standalone/test/SignatureTestable.java (limited to 'src') diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java index 9c761fa..a24346e 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java @@ -41,6 +41,10 @@ public class KeyAgreementTest extends Test { }); } + public static KeyAgreementTest function(KeyAgreementTestable ka, TestCallback callback) { + return new KeyAgreementTest(ka, callback); + } + @Override public String getDescription() { return null; diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java index 51c295c..ef363c3 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java @@ -17,7 +17,7 @@ public class KeyAgreementTestable implements Testable { private ECPublicKey publicKey; private byte[] secret; private boolean hasRun; - private boolean error; + private boolean error = false; private boolean ok; public KeyAgreementTestable(KeyAgreement ka, ECPrivateKey privateKey, ECPublicKey publicKey) { @@ -51,7 +51,6 @@ public class KeyAgreementTestable implements Testable { } catch (InvalidKeyException ikex) { throw new TestException(ikex); } catch (IllegalStateException isex) { - error = true; ok = false; hasRun = true; return; @@ -60,12 +59,12 @@ public class KeyAgreementTestable implements Testable { try { secret = ka.generateSecret(); } catch (IllegalStateException isex) { - error = true; ok = false; hasRun = true; return; } ok = true; + hasRun = true; } @Override diff --git a/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java b/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java index 7a96ba1..0ec4741 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java +++ b/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java @@ -1,12 +1,35 @@ package cz.crcs.ectester.standalone.test; +import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestCallback; import cz.crcs.ectester.common.test.TestException; /** * @author Jan Jancar johny@neuromancer.sk */ public class KeyGenerationTest extends Test { + private KeyGenerationTestable kg; + private TestCallback callback; + + private KeyGenerationTest(KeyGenerationTestable kg, TestCallback callback) { + this.kg = kg; + this.callback = callback; + } + + public static KeyGenerationTest expect(KeyGenerationTestable kg, Result.ExpectedValue expected) { + return new KeyGenerationTest(kg, new TestCallback() { + @Override + public Result apply(KeyGenerationTestable keyGenerationTestable) { + return new Result(Result.Value.fromExpected(expected, keyGenerationTestable.ok(), keyGenerationTestable.error())); + } + }); + } + + public static KeyGenerationTest function(KeyGenerationTestable ka, TestCallback callback) { + return new KeyGenerationTest(ka, callback); + } + @Override public String getDescription() { return null; @@ -14,6 +37,8 @@ public class KeyGenerationTest extends Test { @Override public void run() throws TestException { - + kg.run(); + result = callback.apply(kg); + hasRun = true; } } diff --git a/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java b/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java new file mode 100644 index 0000000..10d02cb --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java @@ -0,0 +1,67 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.TestException; +import cz.crcs.ectester.common.test.Testable; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.spec.AlgorithmParameterSpec; + +public class KeyGenerationTestable implements Testable { + + private KeyPair kp; + private KeyPairGenerator kpg; + private int keysize; + private AlgorithmParameterSpec spec; + private boolean hasRun; + private boolean error = false; + private boolean ok; + + public KeyGenerationTestable(KeyPairGenerator kpg, int keysize) { + this.kpg = kpg; + this.keysize = keysize; + } + + public KeyGenerationTestable(KeyPairGenerator kpg, AlgorithmParameterSpec spec) { + this.kpg = kpg; + this.spec = spec; + } + + public KeyPair getKeyPair() { + return kp; + } + + @Override + public boolean hasRun() { + return hasRun; + } + + @Override + public void run() throws TestException { + try { + if (spec != null) { + kpg.initialize(spec); + } else { + kpg.initialize(keysize); + } + } catch (InvalidAlgorithmParameterException e) { + hasRun = true; + ok = false; + return; + } + kp = kpg.genKeyPair(); + hasRun = true; + ok = true; + } + + @Override + public boolean ok() { + return ok; + } + + @Override + public boolean error() { + return error; + } +} diff --git a/src/cz/crcs/ectester/standalone/test/SignatureTest.java b/src/cz/crcs/ectester/standalone/test/SignatureTest.java index 2102db0..828b84f 100644 --- a/src/cz/crcs/ectester/standalone/test/SignatureTest.java +++ b/src/cz/crcs/ectester/standalone/test/SignatureTest.java @@ -1,12 +1,21 @@ package cz.crcs.ectester.standalone.test; import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestCallback; import cz.crcs.ectester.common.test.TestException; /** * @author Jan Jancar johny@neuromancer.sk */ public class SignatureTest extends Test { + private SignatureTestable sig; + private TestCallback callback; + + private SignatureTest(SignatureTestable sig, TestCallback callback) { + this.sig = sig; + this.callback = callback; + } + @Override public String getDescription() { return null; @@ -14,6 +23,8 @@ public class SignatureTest extends Test { @Override public void run() throws TestException { - + sig.run(); + result = callback.apply(sig); + hasRun = true; } } diff --git a/src/cz/crcs/ectester/standalone/test/SignatureTestable.java b/src/cz/crcs/ectester/standalone/test/SignatureTestable.java new file mode 100644 index 0000000..5f58b4a --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/SignatureTestable.java @@ -0,0 +1,102 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.TestException; +import cz.crcs.ectester.common.test.Testable; + +import java.security.InvalidKeyException; +import java.security.Signature; +import java.security.SignatureException; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; + +public class SignatureTestable implements Testable { + + private Signature sig; + private ECPrivateKey signKey; + private ECPublicKey verifyKey; + private byte[] data; + private byte[] signature; + private boolean verified; + + private boolean hasRun; + private boolean error; + private boolean ok; + + public SignatureTestable(Signature sig, ECPrivateKey signKey, ECPublicKey verifyKey, byte[] data) { + this.sig = sig; + this.signKey = signKey; + this.verifyKey = verifyKey; + this.data = data; + } + + public byte[] getSignature() { + return signature; + } + + public boolean getVerified() { + return verified; + } + + @Override + public boolean hasRun() { + return hasRun; + } + + @Override + public void run() throws TestException { + try { + sig.initSign(signKey); + } catch (InvalidKeyException e) { + throw new TestException(e); + } + + try { + sig.update(data); + } catch (SignatureException e) { + ok = false; + hasRun = true; + return; + } + + try { + signature = sig.sign(); + } catch (SignatureException e) { + ok = false; + hasRun = true; + return; + } + + try { + sig.initVerify(verifyKey); + } catch (InvalidKeyException e) { + throw new TestException(e); + } + + try { + sig.update(data); + } catch (SignatureException e) { + ok = false; + hasRun = true; + return; + } + + try { + verified = sig.verify(signature); + } catch (SignatureException e) { + ok = false; + hasRun = true; + } + ok = true; + hasRun = true; + } + + @Override + public boolean ok() { + return ok; + } + + @Override + public boolean error() { + return error; + } +} -- cgit v1.2.3-70-g09d2 From 80e14c7d3f9eeec34f0236bfb8c595033142756a Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 13 Nov 2017 23:18:35 +0100 Subject: Add KeyPairGenerator idents. --- .../ectester/standalone/ECTesterStandalone.java | 25 +++++++++++++-- .../standalone/consts/KeyPairGeneratorIdent.java | 36 ++++++++++++++++++++++ .../crcs/ectester/standalone/libs/ECLibrary.java | 3 ++ .../ectester/standalone/libs/JavaECLibrary.java | 35 +++++++++++---------- 4 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 src/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java (limited to 'src') diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index 47b7121..016d095 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -3,12 +3,17 @@ package cz.crcs.ectester.standalone; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; import cz.crcs.ectester.standalone.libs.BouncyCastleLib; import cz.crcs.ectester.standalone.libs.ECLibrary; +import cz.crcs.ectester.standalone.libs.JavaECLibrary; import cz.crcs.ectester.standalone.libs.SunECLib; import org.apache.commons.cli.*; import java.io.IOException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** @@ -45,9 +50,23 @@ public class ECTesterStandalone { cfg = new Config(); dataStore = new EC_Store(); for (ECLibrary lib : libs) { - lib.initialize(); - lib.getECKAs(); - lib.getECSigs(); + if (lib instanceof JavaECLibrary) { + JavaECLibrary jlib = (JavaECLibrary) lib; + lib.initialize(); + lib.getECKAs(); + lib.getECSigs(); + for (KeyPairGeneratorIdent ident : lib.getKPGs()) { + try { + KeyPairGenerator kpg = ident.getInstance(jlib.getProvider()); + kpg.initialize(192); + KeyPair kp = kpg.genKeyPair(); + System.out.println(kp); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + } + } + } System.out.println(Arrays.toString(libs)); diff --git a/src/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java b/src/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java new file mode 100644 index 0000000..f806282 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java @@ -0,0 +1,36 @@ +package cz.crcs.ectester.standalone.consts; + +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.util.LinkedList; +import java.util.List; + +public class KeyPairGeneratorIdent extends Ident { + private static final List ALL = new LinkedList<>(); + + static { + ALL.add(new KeyPairGeneratorIdent("EC")); + ALL.add(new KeyPairGeneratorIdent("ECDH")); + ALL.add(new KeyPairGeneratorIdent("ECDSA")); + ALL.add(new KeyPairGeneratorIdent("ECDHC")); + ALL.add(new KeyPairGeneratorIdent("ECMQV")); + } + + public static KeyPairGeneratorIdent get(String ident) { + for (KeyPairGeneratorIdent kg : ALL) { + if (kg.getIdents().contains(ident)) { + return kg; + } + } + return null; + } + + public KeyPairGeneratorIdent(String name, String... aliases) { + super(name, aliases); + } + + public KeyPairGenerator getInstance(Provider provider) throws NoSuchAlgorithmException { + return KeyPairGenerator.getInstance(name, provider); + } +} diff --git a/src/cz/crcs/ectester/standalone/libs/ECLibrary.java b/src/cz/crcs/ectester/standalone/libs/ECLibrary.java index b2792bd..7e26dbe 100644 --- a/src/cz/crcs/ectester/standalone/libs/ECLibrary.java +++ b/src/cz/crcs/ectester/standalone/libs/ECLibrary.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.standalone.libs; import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; +import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; import cz.crcs.ectester.standalone.consts.SignatureIdent; import java.util.Set; @@ -17,5 +18,7 @@ public interface ECLibrary { Set getECSigs(); + Set getKPGs(); + String name(); } diff --git a/src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java b/src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java index f8848da..5689b2b 100644 --- a/src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java +++ b/src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java @@ -1,12 +1,15 @@ package cz.crcs.ectester.standalone.libs; +import cz.crcs.ectester.standalone.consts.Ident; import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; +import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; import cz.crcs.ectester.standalone.consts.SignatureIdent; import java.security.Provider; import java.security.Security; import java.util.HashSet; import java.util.Set; +import java.util.function.Function; /** * @author Jan Jancar johny@neuromancer.sk @@ -39,34 +42,32 @@ public abstract class JavaECLibrary implements ECLibrary { return initialized; } - @Override - public Set getECKAs() { - Set results = new HashSet<>(); + private Set getIdents(String type, Function getter) { + Set results = new HashSet<>(); for (Provider.Service service : provider.getServices()) { - if (service.getType().equals("KeyAgreement")) { - KeyAgreementIdent id = KeyAgreementIdent.get(service.getAlgorithm()); + if (service.getType().equals(type)) { + T id = getter.apply(service.getAlgorithm()); if (id != null) { results.add(id); } } } - System.out.println(results); return results; } + @Override + public Set getECKAs() { + return getIdents("KeyAgreement", KeyAgreementIdent::get); + } + @Override public Set getECSigs() { - Set results = new HashSet<>(); - for (Provider.Service service : provider.getServices()) { - if (service.getType().equals("Signature")) { - SignatureIdent id = SignatureIdent.get(service.getAlgorithm()); - if (id != null) { - results.add(id); - } - } - } - System.out.println(results); - return results; + return getIdents("Signature", SignatureIdent::get); + } + + @Override + public Set getKPGs() { + return getIdents("KeyPairGenerator", KeyPairGeneratorIdent::get); } @Override -- cgit v1.2.3-70-g09d2 From 82a0399051d3bc059deb6923512092b31971d352 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 14 Nov 2017 03:04:10 +0100 Subject: Extract common CLI methods to CLITools. --- src/cz/crcs/ectester/common/CLITools.java | 56 ++++++++++++++++++++++ src/cz/crcs/ectester/reader/ECTesterReader.java | 41 ++-------------- .../ectester/standalone/ECTesterStandalone.java | 38 +++++++-------- .../standalone/test/KeyGenerationTestable.java | 6 +-- 4 files changed, 80 insertions(+), 61 deletions(-) create mode 100644 src/cz/crcs/ectester/common/CLITools.java (limited to 'src') diff --git a/src/cz/crcs/ectester/common/CLITools.java b/src/cz/crcs/ectester/common/CLITools.java new file mode 100644 index 0000000..57cea64 --- /dev/null +++ b/src/cz/crcs/ectester/common/CLITools.java @@ -0,0 +1,56 @@ +package cz.crcs.ectester.common; + +import cz.crcs.ectester.common.ec.EC_Category; +import cz.crcs.ectester.common.ec.EC_Data; +import cz.crcs.ectester.data.EC_Store; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; + +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CLITools { + + /** + * Print help. + */ + public static void help(String prog, String header, Options options, String footer, boolean usage) { + HelpFormatter help = new HelpFormatter(); + help.setOptionComparator(null); + help.printHelp(prog, header, options, footer, usage); + } + + /** + * Print version info. + */ + public static void version(String description, String license) { + System.out.println(description); + System.out.println(license); + } + + /** + * List categories and named curves. + */ + public static void listNamed(EC_Store dataStore, String named) { + Map categories = dataStore.getCategories(); + if (named == null) { + // print all categories, briefly + for (EC_Category cat : categories.values()) { + System.out.println(cat); + } + } else if (categories.containsKey(named)) { + // print given category + System.out.println(categories.get(named)); + } else { + // print given object + EC_Data object = dataStore.getObject(EC_Data.class, named); + if (object != null) { + System.out.println(object); + } else { + System.err.println("Named object " + named + " not found!"); + } + } + } +} diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 0bbe8f7..c51430d 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -23,6 +23,7 @@ package cz.crcs.ectester.reader; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.CLITools; import cz.crcs.ectester.common.Util; import cz.crcs.ectester.common.ec.EC_Category; import cz.crcs.ectester.common.ec.EC_Data; @@ -79,11 +80,10 @@ public class ECTesterReader { //if help, print and quit if (cli.hasOption("help")) { - help(); + CLITools.help("ECTesterReader.jar", CLI_HEADER, opts, CLI_FOOTER, true); return; } else if (cli.hasOption("version")) { - System.out.println(DESCRIPTION); - System.out.println(LICENSE); + CLITools.version(DESCRIPTION, LICENSE); return; } cfg = new Config(); @@ -96,7 +96,7 @@ public class ECTesterReader { dataStore = new EC_Store(); //if list, print and quit if (cli.hasOption("list-named")) { - list(); + CLITools.listNamed(dataStore, cli.getOptionValue("list-named")); return; } @@ -311,39 +311,6 @@ public class ECTesterReader { return parser.parse(opts, args); } - /** - * Prints help. - */ - private void help() { - HelpFormatter help = new HelpFormatter(); - help.setOptionComparator(null); - help.printHelp("ECTesterReader.jar", CLI_HEADER, opts, CLI_FOOTER, true); - } - - /** - * List categories and named curves. - */ - private void list() { - Map categories = dataStore.getCategories(); - if (cfg.listNamed == null) { - // print all categories, briefly - for (EC_Category cat : categories.values()) { - System.out.println(cat); - } - } else if (categories.containsKey(cfg.listNamed)) { - // print given category - System.out.println(categories.get(cfg.listNamed)); - } else { - // print given object - EC_Data object = dataStore.getObject(EC_Data.class, cfg.listNamed); - if (object != null) { - System.out.println(object); - } else { - System.err.println("Named object " + cfg.listNamed + " not found!"); - } - } - } - /** * Exports default card/simulation EC domain parameters to output file. * diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index 016d095..e8998ff 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.standalone; import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.CLITools; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; @@ -40,15 +41,21 @@ public class ECTesterStandalone { CommandLine cli = parseArgs(args); if (cli.hasOption("help")) { - help(); + CLITools.help("ECTesterStandalone.jar", CLI_HEADER, opts, CLI_FOOTER, true); return; } else if (cli.hasOption("version")) { - version(); + CLITools.version(DESCRIPTION, LICENSE); return; } cfg = new Config(); dataStore = new EC_Store(); + + if (cli.hasOption("list-named")) { + CLITools.listNamed(dataStore, cli.getOptionValue("list-named")); + return; + } + for (ECLibrary lib : libs) { if (lib instanceof JavaECLibrary) { JavaECLibrary jlib = (JavaECLibrary) lib; @@ -72,7 +79,7 @@ public class ECTesterStandalone { if (cli.hasOption("generate")) { generate(); - } else if (cli.hasOption("libs")) { + } else if (cli.hasOption("list-libs")) { listLibraries(); } @@ -86,31 +93,20 @@ public class ECTesterStandalone { actions.setRequired(true); actions.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build()); actions.addOption(Option.builder("h").longOpt("help").desc("Print help.").build()); + actions.addOption(Option.builder("e").longOpt("export").desc("Export the defaut curve parameters of the card(if any).").build()); actions.addOption(Option.builder("g").longOpt("generate").desc("Generate [amount] of EC keys.").hasArg().argName("amount").optionalArg(true).build()); - actions.addOption(Option.builder("ls").longOpt("libs").desc("List supported libraries.").build()); + actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. [test_suite]:\n- default:\n- invalid:\n- wrong:\n- composite:\n- test-vectors:").hasArg().argName("test_suite").optionalArg(true).build()); + 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()); + actions.addOption(Option.builder("ln").longOpt("list-named").desc("Print the list of supported named curves and keys.").hasArg().argName("what").optionalArg(true).build()); + actions.addOption(Option.builder("ls").longOpt("list-libs").desc("List supported libraries.").build()); opts.addOptionGroup(actions); CommandLineParser parser = new DefaultParser(); return parser.parse(opts, args); } - /** - * Prints help. - */ - private void help() { - HelpFormatter help = new HelpFormatter(); - help.setOptionComparator(null); - help.printHelp("ECTesterStandalone.jar", CLI_HEADER, opts, CLI_FOOTER, true); - } - - /** - * Prints version info. - */ - private void version() { - System.out.println(DESCRIPTION); - System.out.println(LICENSE); - } - /** * */ diff --git a/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java b/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java index 10d02cb..8ad425b 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java +++ b/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java @@ -6,14 +6,14 @@ import cz.crcs.ectester.common.test.Testable; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; -import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECParameterSpec; public class KeyGenerationTestable implements Testable { private KeyPair kp; private KeyPairGenerator kpg; private int keysize; - private AlgorithmParameterSpec spec; + private ECParameterSpec spec; private boolean hasRun; private boolean error = false; private boolean ok; @@ -23,7 +23,7 @@ public class KeyGenerationTestable implements Testable { this.keysize = keysize; } - public KeyGenerationTestable(KeyPairGenerator kpg, AlgorithmParameterSpec spec) { + public KeyGenerationTestable(KeyPairGenerator kpg, ECParameterSpec spec) { this.kpg = kpg; this.spec = spec; } -- cgit v1.2.3-70-g09d2 From 7758239163e6c81f985fa4e33ad1c0cb57627f0e Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 15 Nov 2017 01:00:13 +0100 Subject: Add Tree-like CLI parsing utilities. --- src/cz/crcs/ectester/common/CLITools.java | 56 --------- src/cz/crcs/ectester/common/cli/CLITools.java | 90 ++++++++++++++ src/cz/crcs/ectester/common/cli/ParserOptions.java | 25 ++++ .../crcs/ectester/common/cli/TreeCommandLine.java | 134 +++++++++++++++++++++ src/cz/crcs/ectester/common/cli/TreeParser.java | 75 ++++++++++++ src/cz/crcs/ectester/reader/ECTesterReader.java | 4 +- .../ectester/standalone/ECTesterStandalone.java | 5 +- 7 files changed, 327 insertions(+), 62 deletions(-) delete mode 100644 src/cz/crcs/ectester/common/CLITools.java create mode 100644 src/cz/crcs/ectester/common/cli/CLITools.java create mode 100644 src/cz/crcs/ectester/common/cli/ParserOptions.java create mode 100644 src/cz/crcs/ectester/common/cli/TreeCommandLine.java create mode 100644 src/cz/crcs/ectester/common/cli/TreeParser.java (limited to 'src') diff --git a/src/cz/crcs/ectester/common/CLITools.java b/src/cz/crcs/ectester/common/CLITools.java deleted file mode 100644 index 57cea64..0000000 --- a/src/cz/crcs/ectester/common/CLITools.java +++ /dev/null @@ -1,56 +0,0 @@ -package cz.crcs.ectester.common; - -import cz.crcs.ectester.common.ec.EC_Category; -import cz.crcs.ectester.common.ec.EC_Data; -import cz.crcs.ectester.data.EC_Store; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Options; - -import java.util.Map; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class CLITools { - - /** - * Print help. - */ - public static void help(String prog, String header, Options options, String footer, boolean usage) { - HelpFormatter help = new HelpFormatter(); - help.setOptionComparator(null); - help.printHelp(prog, header, options, footer, usage); - } - - /** - * Print version info. - */ - public static void version(String description, String license) { - System.out.println(description); - System.out.println(license); - } - - /** - * List categories and named curves. - */ - public static void listNamed(EC_Store dataStore, String named) { - Map categories = dataStore.getCategories(); - if (named == null) { - // print all categories, briefly - for (EC_Category cat : categories.values()) { - System.out.println(cat); - } - } else if (categories.containsKey(named)) { - // print given category - System.out.println(categories.get(named)); - } else { - // print given object - EC_Data object = dataStore.getObject(EC_Data.class, named); - if (object != null) { - System.out.println(object); - } else { - System.err.println("Named object " + named + " not found!"); - } - } - } -} diff --git a/src/cz/crcs/ectester/common/cli/CLITools.java b/src/cz/crcs/ectester/common/cli/CLITools.java new file mode 100644 index 0000000..8f34f62 --- /dev/null +++ b/src/cz/crcs/ectester/common/cli/CLITools.java @@ -0,0 +1,90 @@ +package cz.crcs.ectester.common.cli; + +import cz.crcs.ectester.common.ec.EC_Category; +import cz.crcs.ectester.common.ec.EC_Data; +import cz.crcs.ectester.data.EC_Store; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CLITools { + + /** + * Print help. + */ + public static void help(String prog, String header, Options options, String footer, boolean usage) { + HelpFormatter help = new HelpFormatter(); + help.setOptionComparator(null); + help.printHelp(prog, header, options, footer, usage); + } + + private static void help(HelpFormatter help, PrintWriter pw, CommandLineParser cli, int depth) { + if (cli instanceof TreeParser) { + TreeParser tp = (TreeParser) cli; + tp.getParsers().forEach((key, value) -> { + help.printWrapped(pw, HelpFormatter.DEFAULT_WIDTH, String.format("%" + String.valueOf(depth) + "s" + key + ":", " ")); + help.printOptions(pw, HelpFormatter.DEFAULT_WIDTH, value.getOptions(), HelpFormatter.DEFAULT_LEFT_PAD + depth, HelpFormatter.DEFAULT_DESC_PAD); + pw.println(); + CLITools.help(help, pw, value.getParser(), depth + 1); + }); + } + } + + /** + * Print tree help. + */ + public static void help(String prog, String header, Options baseOpts, TreeParser baseParser, String footer, boolean usage) { + HelpFormatter help = new HelpFormatter(); + help.setOptionComparator(null); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + if (usage) { + help.printUsage(pw, HelpFormatter.DEFAULT_WIDTH, prog, baseOpts); + } + help.printWrapped(pw, HelpFormatter.DEFAULT_WIDTH, header); + help.printOptions(pw, HelpFormatter.DEFAULT_WIDTH, baseOpts, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD); + pw.println(); + help(help, pw, baseParser, 1); + help.printWrapped(pw, HelpFormatter.DEFAULT_WIDTH, footer); + System.out.println(sw.toString()); + } + + /** + * Print version info. + */ + public static void version(String description, String license) { + System.out.println(description); + System.out.println(license); + } + + /** + * List categories and named curves. + */ + public static void listNamed(EC_Store dataStore, String named) { + Map categories = dataStore.getCategories(); + if (named == null) { + // print all categories, briefly + for (EC_Category cat : categories.values()) { + System.out.println(cat); + } + } else if (categories.containsKey(named)) { + // print given category + System.out.println(categories.get(named)); + } else { + // print given object + EC_Data object = dataStore.getObject(EC_Data.class, named); + if (object != null) { + System.out.println(object); + } else { + System.err.println("Named object " + named + " not found!"); + } + } + } +} diff --git a/src/cz/crcs/ectester/common/cli/ParserOptions.java b/src/cz/crcs/ectester/common/cli/ParserOptions.java new file mode 100644 index 0000000..4216ce3 --- /dev/null +++ b/src/cz/crcs/ectester/common/cli/ParserOptions.java @@ -0,0 +1,25 @@ +package cz.crcs.ectester.common.cli; + +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.Options; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class ParserOptions { + private CommandLineParser parser; + private Options options; + + public ParserOptions(CommandLineParser parser, Options options) { + this.parser = parser; + this.options = options; + } + + public CommandLineParser getParser() { + return parser; + } + + public Options getOptions() { + return options; + } +} diff --git a/src/cz/crcs/ectester/common/cli/TreeCommandLine.java b/src/cz/crcs/ectester/common/cli/TreeCommandLine.java new file mode 100644 index 0000000..ef6079e --- /dev/null +++ b/src/cz/crcs/ectester/common/cli/TreeCommandLine.java @@ -0,0 +1,134 @@ +package cz.crcs.ectester.common.cli; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.ParseException; + +import java.util.Iterator; +import java.util.Properties; +import java.util.function.BiFunction; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TreeCommandLine extends CommandLine { + private String name = ""; + private TreeCommandLine next; + private CommandLine cli; + + public TreeCommandLine(CommandLine cli, TreeCommandLine next) { + this.cli = cli; + this.next = next; + } + + public TreeCommandLine(String name, CommandLine cli, TreeCommandLine next) { + this(cli, next); + this.name = name; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public String getNextName() { + if (next != null) { + return next.getName(); + } + return null; + } + + public TreeCommandLine getNext() { + return next; + } + + public CommandLine getThis() { + return cli; + } + + private T getOption(String opt, BiFunction getter, T defaultValue) { + if (opt.contains(".")) { + String[] parts = opt.split(".", 2); + if (next != null && parts[0].equals(next.getName())) { + return getter.apply(next, parts[1]); + } + return defaultValue; + } + return getter.apply(cli, opt); + } + + @Override + public boolean hasOption(String opt) { + return getOption(opt, CommandLine::hasOption, false); + } + + @Override + public boolean hasOption(char opt) { + return cli.hasOption(opt); + } + + @Override + public Object getParsedOptionValue(String opt) throws ParseException { + if (opt.contains(".")) { + String[] parts = opt.split(".", 2); + if (next != null && parts[0].equals(next.getName())) { + return next.getParsedOptionValue(parts[1]); + } + return null; + } + return cli.getParsedOptionValue(opt); + } + + @Override + public Object getOptionObject(char opt) { + return cli.getOptionObject(opt); + } + + @Override + public String getOptionValue(String opt) { + return getOption(opt, CommandLine::getOptionValue, null); + } + + @Override + public String getOptionValue(char opt) { + return cli.getOptionValue(opt); + } + + @Override + public String[] getOptionValues(String opt) { + return getOption(opt, CommandLine::getOptionValues, null); + } + + @Override + public String[] getOptionValues(char opt) { + return cli.getOptionValues(opt); + } + + @Override + public String getOptionValue(String opt, String defaultValue) { + return getOption(opt, CommandLine::getOptionValue, defaultValue); + } + + @Override + public String getOptionValue(char opt, String defaultValue) { + return cli.getOptionValue(opt, defaultValue); + } + + @Override + public Properties getOptionProperties(String opt) { + return getOption(opt, CommandLine::getOptionProperties, new Properties()); + } + + @Override + public Iterator