From a2f5316ad96b6e78844c371f8dd5483095cf4af3 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 12 Nov 2017 12:38:04 +0100 Subject: Introduce ECTesterStandalone. --- src/cz/crcs/ectester/standalone/ECTesterStandalone.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/cz/crcs/ectester/standalone/ECTesterStandalone.java (limited to 'src/cz/crcs/ectester/standalone/ECTesterStandalone.java') diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java new file mode 100644 index 0000000..cae4bb9 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -0,0 +1,13 @@ +package cz.crcs.ectester.standalone; + +public class ECTesterStandalone { + + private void run(String[] args) { + + } + + public static void main(String[] args) { + ECTesterStandalone app = new ECTesterStandalone(); + app.run(args); + } +} -- cgit v1.2.3-70-g09d2 From e329190e496ecf847cfd7afa886ac08cacb2fc92 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 12 Nov 2017 17:23:04 +0100 Subject: Add BouncyCastle library. Sketch out ECTesterStandalone. --- docs/LIBS.md | 16 ++++ lib/bcprov-jdk15on-1.58.jar | Bin 0 -> 3955990 bytes nbproject/standalone/manifest.mf | 2 +- nbproject/standalone/project.properties | 1 + src/cz/crcs/ectester/common/ec/EC_Data.java | 8 +- src/cz/crcs/ectester/common/ec/EC_Params.java | 43 +++++++++++ src/cz/crcs/ectester/reader/ECTesterReader.java | 2 +- .../crcs/ectester/reader/test/TestVectorSuite.java | 4 +- .../ectester/standalone/ECTesterStandalone.java | 86 +++++++++++++++++++++ .../ectester/standalone/libs/BouncyCastleLib.java | 21 +++++ 10 files changed, 175 insertions(+), 8 deletions(-) create mode 100644 docs/LIBS.md create mode 100644 lib/bcprov-jdk15on-1.58.jar create mode 100644 src/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java (limited to 'src/cz/crcs/ectester/standalone/ECTesterStandalone.java') diff --git a/docs/LIBS.md b/docs/LIBS.md new file mode 100644 index 0000000..97a80ec --- /dev/null +++ b/docs/LIBS.md @@ -0,0 +1,16 @@ +# Libraries + +Libraries with at least some ECC support: + + - [BouncyCastle](https://bouncycastle.org/java.html) + - [Botan](https://botan.randombit.net/) + - [Crypto++](https://cryptopp.com/) + - [libgcrypt](https://www.gnupg.org/related_software/libgcrypt/) + - [libtomcrypt](http://www.libtom.net/LibTomCrypt/) + - [mbedTLS](https://tls.mbed.org/) + - [Nettle](http://www.lysator.liu.se/~nisse/nettle/) + - [OpenSSL](https://www.openssl.org/) + - [OpenSSL (FIPS mode)](https://www.openssl.org/docs/fipsnotes.html) + - [Sun EC](https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunEC) + - [Microsoft CNG](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376210(v=vs.85).aspx) + - [Microsoft .NET crypto](https://docs.microsoft.com/en-us/dotnet/standard/security/cryptography-model) \ No newline at end of file diff --git a/lib/bcprov-jdk15on-1.58.jar b/lib/bcprov-jdk15on-1.58.jar new file mode 100644 index 0000000..dae02cb Binary files /dev/null and b/lib/bcprov-jdk15on-1.58.jar differ diff --git a/nbproject/standalone/manifest.mf b/nbproject/standalone/manifest.mf index 316e308..02f1e3e 100644 --- a/nbproject/standalone/manifest.mf +++ b/nbproject/standalone/manifest.mf @@ -1,4 +1,4 @@ Manifest-Version: 1.0 -Class-Path: lib/jcardsim-3.0.4-SNAPSHOT.jar lib/commons-cli-1.3.1.jar lib/snakeyaml-1.19.jar +Class-Path: lib/bcprov-jdk15on-1.58.jar lib/jcardsim-3.0.4-SNAPSHOT.jar lib/commons-cli-1.3.1.jar lib/snakeyaml-1.19.jar Main-Class: cz.crcs.ectester.standalone.ECTesterStandalone diff --git a/nbproject/standalone/project.properties b/nbproject/standalone/project.properties index 1952f1d..367ec51 100644 --- a/nbproject/standalone/project.properties +++ b/nbproject/standalone/project.properties @@ -33,6 +33,7 @@ excludes= includes=**/common/**,**/standalone/**,**/data/**,**/applet/* jar.compress=false javac.classpath=\ + lib/bcprov-jdk15on-1.58.jar:\ lib/jcardsim-3.0.4-SNAPSHOT.jar:\ lib/commons-cli-1.3.1.jar:\ lib/snakeyaml-1.19.jar diff --git a/src/cz/crcs/ectester/common/ec/EC_Data.java b/src/cz/crcs/ectester/common/ec/EC_Data.java index d308261..acd282a 100644 --- a/src/cz/crcs/ectester/common/ec/EC_Data.java +++ b/src/cz/crcs/ectester/common/ec/EC_Data.java @@ -55,12 +55,12 @@ public abstract class EC_Data { return data; } - public boolean hasData() { - return data != null; + public byte[] getData(int index) { + return data[index]; } - public byte[] getParam(int index) { - return data[index]; + public boolean hasData() { + return data != null; } public byte[] flatten() { diff --git a/src/cz/crcs/ectester/common/ec/EC_Params.java b/src/cz/crcs/ectester/common/ec/EC_Params.java index d50ebb0..3fada93 100644 --- a/src/cz/crcs/ectester/common/ec/EC_Params.java +++ b/src/cz/crcs/ectester/common/ec/EC_Params.java @@ -44,6 +44,49 @@ public class EC_Params extends EC_Data { return params; } + public byte[][] getParam(short param) { + if (!hasParam(param)) { + return null; + } + if (Integer.bitCount(param) != 1) { + return null; + } + short paramMask = EC_Consts.PARAMETER_FP; + byte[][] result = null; + int i = 0; + while (paramMask <= EC_Consts.PARAMETER_S) { + short masked = (short) (this.params & param & paramMask); + short shallow = (short) (this.params & paramMask); + if (masked != 0) { + if (masked == EC_Consts.PARAMETER_F2M) { + result = new byte[4][]; + result[0] = data[i].clone(); + result[1] = data[i+1].clone(); + result[2] = data[i+2].clone(); + result[3] = data[i+3].clone(); + break; + } + if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) { + result = new byte[2][]; + result[0] = data[i].clone(); + result[1] = data[i+1].clone(); + break; + } + result = new byte[1][]; + result[0] = data[i].clone(); + } + if (shallow == EC_Consts.PARAMETER_F2M) { + i += 4; + } else if (shallow == EC_Consts.PARAMETER_G || shallow == EC_Consts.PARAMETER_W) { + i += 2; + } else if (shallow != 0) { + i++; + } + paramMask = (short) (paramMask << 1); + } + return result; + } + public boolean hasParam(short param) { return (params & param) != 0; } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index e13a683..0bbe8f7 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -63,7 +63,7 @@ public class ECTesterReader { private Options opts = new Options(); private static final String VERSION = "v0.1.0"; - private static final String DESCRIPTION = "ECTesterReader " + VERSION + ", a javacard Elliptic Curve Cryptograhy support tester/utility."; + private static final String DESCRIPTION = "ECTesterReader " + VERSION + ", a javacard Elliptic Curve Cryptography support tester/utility."; private static final String LICENSE = "MIT Licensed\nCopyright (c) 2016-2017 Petr Svenda "; private static final String CLI_HEADER = "\n" + DESCRIPTION + "\n\n"; private static final String CLI_FOOTER = "\n" + LICENSE; diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 668056b..3f11a79 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -72,8 +72,8 @@ public class TestVectorSuite extends TestSuite { return new Result(Value.FAILURE, "ECDH was unsuccessful."); if (!dh.hasSecret()) return new Result(Value.FAILURE, "ECDH response did not contain the derived secret."); - if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { - int firstDiff = Util.diffBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength()); + if (!Util.compareBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength())) { + int firstDiff = Util.diffBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength()); return new Result(Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); } return new Result(Value.SUCCESS); diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index cae4bb9..d2cbce1 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -1,8 +1,90 @@ 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 org.apache.commons.cli.*; + +import java.io.IOException; + +/** + * Standalone part of ECTester, a tool for testing Elliptic curve implementations in software libraries. + * + * @author Jan Jancar johny@neuromancer.sk + * @version v0.1.0 + */ public class ECTesterStandalone { + private EC_Store dataStore; + private Config cfg; + + private Options opts = new Options(); + private static final String VERSION = "v0.1.0"; + private static final String DESCRIPTION = "ECTesterStandalone " + VERSION + ", an Elliptic Curve Cryptography support tester/utility."; + private static final String LICENSE = "MIT Licensed\nCopyright (c) 2016-2017 Petr Svenda "; + private static final String CLI_HEADER = "\n" + DESCRIPTION + "\n\n"; + private static final String CLI_FOOTER = "\n" + LICENSE; + private void run(String[] args) { + try { + CommandLine cli = parseArgs(args); + + if (cli.hasOption("help")) { + help(); + return; + } else if (cli.hasOption("version")) { + version(); + return; + } + + cfg = new Config(); + dataStore = new EC_Store(); + + if (cli.hasOption("generate")) { + generate(); + } + + } catch (ParseException | IOException ex) { + System.err.println(ex.getMessage()); + } + } + + private CommandLine parseArgs(String[] args) throws ParseException { + OptionGroup actions = new OptionGroup(); + 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("g").longOpt("generate").desc("Generate [amount] of EC keys.").hasArg().argName("amount").optionalArg(true).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); + } + + /** + * + */ + private void generate() { + EC_Curve curve = dataStore.getObject(EC_Curve.class, "secg/secp192r1"); + byte[] fp = curve.getParam(EC_Consts.PARAMETER_FP)[0]; } @@ -10,4 +92,8 @@ public class ECTesterStandalone { ECTesterStandalone app = new ECTesterStandalone(); app.run(args); } + + public static class Config { + + } } diff --git a/src/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java b/src/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java new file mode 100644 index 0000000..78da737 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java @@ -0,0 +1,21 @@ +package cz.crcs.ectester.standalone.libs; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import java.security.Security; + +public class BouncyCastleLib { + + public BouncyCastleLib() { + + } + + public boolean setUp() { + try { + Security.addProvider(new BouncyCastleProvider()); + } catch (NullPointerException | SecurityException ignored) { + return false; + } + return true; + } + +} -- cgit v1.2.3-70-g09d2 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/cz/crcs/ectester/standalone/ECTesterStandalone.java') 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 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/cz/crcs/ectester/standalone/ECTesterStandalone.java') 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/cz/crcs/ectester/standalone/ECTesterStandalone.java') 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/cz/crcs/ectester/standalone/ECTesterStandalone.java') 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