diff options
| author | J08nY | 2018-07-02 16:55:37 +0200 |
|---|---|---|
| committer | J08nY | 2018-07-02 16:55:37 +0200 |
| commit | c8b36d3491bb2c5a3eb0632a2e1ead7d5ea9f7c8 (patch) | |
| tree | 3b833a3ac76100226724b9ff640c5d720ed45b1c | |
| parent | 957afe308fd9f648894076fe8e348c4a35669499 (diff) | |
| download | ECTester-c8b36d3491bb2c5a3eb0632a2e1ead7d5ea9f7c8.tar.gz ECTester-c8b36d3491bb2c5a3eb0632a2e1ead7d5ea9f7c8.tar.zst ECTester-c8b36d3491bb2c5a3eb0632a2e1ead7d5ea9f7c8.zip | |
| -rw-r--r-- | src/cz/crcs/ectester/common/cli/CLITools.java | 4 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/cli/Colors.java | 93 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_Category.java | 12 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/data/categories.xml | 4 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/ECTesterReader.java | 82 |
5 files changed, 149 insertions, 46 deletions
diff --git a/src/cz/crcs/ectester/common/cli/CLITools.java b/src/cz/crcs/ectester/common/cli/CLITools.java index 4aa58b0..a9d036e 100644 --- a/src/cz/crcs/ectester/common/cli/CLITools.java +++ b/src/cz/crcs/ectester/common/cli/CLITools.java @@ -22,7 +22,7 @@ public class CLITools { 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); + help.printHelp(Colors.bold(prog), header, options, footer, usage); } private static void help(HelpFormatter help, PrintWriter pw, CommandLineParser cli, Options opts, int depth) { @@ -97,7 +97,7 @@ public class CLITools { StringWriter uw = new StringWriter(); PrintWriter upw = new PrintWriter(uw); usage(help, upw, baseParser, baseOpts); - pw.print("usage: " + prog); + pw.print("usage: " + Colors.bold(prog)); help.printWrapped(pw, HelpFormatter.DEFAULT_WIDTH, uw.toString()); upw.close(); pw.println(); diff --git a/src/cz/crcs/ectester/common/cli/Colors.java b/src/cz/crcs/ectester/common/cli/Colors.java new file mode 100644 index 0000000..cdc42e8 --- /dev/null +++ b/src/cz/crcs/ectester/common/cli/Colors.java @@ -0,0 +1,93 @@ +package cz.crcs.ectester.common.cli; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author Diogo Nunes + * @author Jan Jancar johny@neuromancer.sk + * Adapted from https://github.com/dialex/JCDP/ + */ +public class Colors { + public static boolean enabled = false; + + public interface ANSIParam { + } + + public enum Foreground implements ANSIParam { + BLACK("30"), RED("31"), GREEN("32"), YELLOW("33"), BLUE("34"), MAGENTA("35"), CYAN("36"), WHITE("37"), NONE(""); + private final String code; + + Foreground(String code) { + this.code = code; + } + + @Override + public String toString() { + return code; + } + } + + public enum Background implements ANSIParam { + BLACK("40"), RED("41"), GREEN("42"), YELLOW("43"), BLUE("44"), MAGENTA("45"), CYAN("46"), WHITE("47"), NONE(""); + private final String code; + + Background(String code) { + this.code = code; + } + + @Override + public String toString() { + return code; + } + } + + public enum Attribute implements ANSIParam { + CLEAR("0"), BOLD("1"), LIGHT("1"), DARK("2"), UNDERLINE("4"), REVERSE("7"), HIDDEN("8"), NONE(""); + private final String code; + + Attribute(String code) { + this.code = code; + } + + @Override + public String toString() { + return code; + } + } + + private static final String PREFIX = "\033["; + private static final String SEPARATOR = ";"; + private static final String POSTFIX = "m"; + + public static String colored(String text, ANSIParam... params) { + if (!enabled) { + return text; + } + Optional<Foreground> fg = Arrays.stream(params).filter(Foreground.class::isInstance).map(Foreground.class::cast).findFirst(); + Optional<Background> bg = Arrays.stream(params).filter(Background.class::isInstance).map(Background.class::cast).findFirst(); + List<Attribute> attr = Arrays.stream(params).filter(Attribute.class::isInstance).distinct().map(Attribute.class::cast).collect(Collectors.toList()); + + List<ANSIParam> apply = new LinkedList<>(); + apply.addAll(attr); + fg.ifPresent(apply::add); + bg.ifPresent(apply::add); + List<String> codes = apply.stream().map(Object::toString).collect(Collectors.toList()); + return PREFIX + String.join(SEPARATOR, codes) + POSTFIX + text + PREFIX + Attribute.CLEAR + POSTFIX; + } + + public static String error(String text) { + return colored(text, Foreground.RED, Attribute.BOLD); + } + + public static String ok(String text) { + return colored(text, Foreground.GREEN, Attribute.BOLD); + } + + public static String bold(String text) { + return colored(text, Attribute.BOLD); + } +}
\ No newline at end of file diff --git a/src/cz/crcs/ectester/common/ec/EC_Category.java b/src/cz/crcs/ectester/common/ec/EC_Category.java index 32a788d..9c65f3b 100644 --- a/src/cz/crcs/ectester/common/ec/EC_Category.java +++ b/src/cz/crcs/ectester/common/ec/EC_Category.java @@ -1,5 +1,7 @@ package cz.crcs.ectester.common.ec; +import cz.crcs.ectester.common.cli.Colors; + import java.util.Collections; import java.util.Map; import java.util.Objects; @@ -72,13 +74,13 @@ public class EC_Category { @Override public String toString() { StringBuilder out = new StringBuilder(); - out.append("\t- ").append(name).append((desc == null || desc.equals("")) ? "" : ": " + desc); + out.append("\t- ").append(Colors.bold(name)).append((desc == null || desc.equals("")) ? "" : ": " + desc); out.append(System.lineSeparator()); Map<String, EC_Curve> curves = getObjects(EC_Curve.class); int size = curves.size(); if (size > 0) { - out.append("\t\tCurves: "); + out.append(Colors.bold("\t\tCurves: ")); for (Map.Entry<String, EC_Curve> curve : curves.entrySet()) { out.append(curve.getKey()); size--; @@ -91,7 +93,7 @@ public class EC_Category { Map<String, EC_Key> keys = getObjects(EC_Key.class); size = keys.size(); if (size > 0) { - out.append("\t\tKeys: "); + out.append(Colors.bold("\t\tKeys: ")); for (Map.Entry<String, EC_Key> key : keys.entrySet()) { out.append(key.getKey()); size--; @@ -104,7 +106,7 @@ public class EC_Category { Map<String, EC_Keypair> keypairs = getObjects(EC_Keypair.class); size = keypairs.size(); if (size > 0) { - out.append("\t\tKeypairs: "); + out.append(Colors.bold("\t\tKeypairs: ")); for (Map.Entry<String, EC_Keypair> key : keypairs.entrySet()) { out.append(key.getKey()); size--; @@ -117,7 +119,7 @@ public class EC_Category { Map<String, EC_KAResult> results = getObjects(EC_KAResult.class); size = results.size(); if (size > 0) { - out.append("\t\tResults: "); + out.append(Colors.bold("\t\tResults: ")); for (Map.Entry<String, EC_KAResult> result : results.entrySet()) { out.append(result.getKey()); size--; diff --git a/src/cz/crcs/ectester/data/categories.xml b/src/cz/crcs/ectester/data/categories.xml index b51011a..e725db0 100644 --- a/src/cz/crcs/ectester/data/categories.xml +++ b/src/cz/crcs/ectester/data/categories.xml @@ -72,12 +72,12 @@ <category> <name>composite</name> <directory>composite</directory> - <desc>Composite order curves, with points of very small order pre-generated.</desc> + <desc>Composite order curves, with points of very small order pre-generated. Also curves with order of a product of two large primes.</desc> </category> <category> <name>wrong</name> <directory>wrong</directory> - <desc>Wrong field curves. These should definitely give an error when used. Since the "prime" used for the field are not prime, and the field polynomials are also not irreducible. Simply put these parameters don't specify a valid elliptic curve.</desc> + <desc>Wrong field curves. These should definitely give an error when used. Since the "prime" used for the field is not prime, and the field polynomials are also not irreducible. Simply put these parameters don't specify a valid elliptic curve.</desc> </category> <category> <name>test</name> diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 92b5781..f81b95a 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -25,6 +25,7 @@ package cz.crcs.ectester.reader; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.cli.CLITools; +import cz.crcs.ectester.common.cli.Colors; import cz.crcs.ectester.common.ec.EC_Params; import cz.crcs.ectester.common.output.OutputLogger; import cz.crcs.ectester.common.output.TestWriter; @@ -81,6 +82,9 @@ public class ECTesterReader { try { CommandLine cli = parseArgs(args); + cfg = new Config(); + boolean optsOk = cfg.readOptions(cli); + //if help, print and quit if (cli.hasOption("help")) { CLITools.help("ECTesterReader.jar", CLI_HEADER, opts, CLI_FOOTER, true); @@ -89,10 +93,9 @@ public class ECTesterReader { CLITools.version(DESCRIPTION, LICENSE); return; } - cfg = new Config(); - //if not, read other options first, into attributes, then do action - if (!cfg.readOptions(cli)) { + //if opts failed, quit + if (!optsOk) { return; } @@ -113,12 +116,12 @@ public class ECTesterReader { //connect or simulate connection if (cfg.simulate) { if (!cardManager.prepareLocalSimulatorApplet(AID, INSTALL_DATA, ECTesterApplet.class)) { - System.err.println("Failed to establish a simulator."); + System.err.println(Colors.error("Failed to establish a simulator.")); System.exit(1); } } else { if (!cardManager.connectToCardSelect()) { - System.err.println("Failed to connect to card."); + System.err.println(Colors.error("Failed to connect to card.")); System.exit(1); } cardManager.send(SELECT_ECTESTERAPPLET); @@ -147,7 +150,7 @@ public class ECTesterReader { logger.close(); } catch (MissingOptionException moex) { - System.err.println("Missing required options, one of:"); + System.err.println(Colors.error("Missing required options, one of:")); for (Object opt : moex.getMissingOptions().toArray()) { if (opt instanceof OptionGroup) { for (Option o : ((OptionGroup) opt).getOptions()) { @@ -175,13 +178,13 @@ public class ECTesterReader { } } } catch (MissingArgumentException maex) { - System.err.println("Option, " + maex.getOption().getOpt() + " requires an argument: " + maex.getOption().getArgName()); + System.err.println(Colors.error("Option, " + maex.getOption().getOpt() + " requires an argument: " + maex.getOption().getArgName())); } catch (NumberFormatException nfex) { - System.err.println("Not a number. " + nfex.getMessage()); + System.err.println(Colors.error("Not a number. " + nfex.getMessage())); } catch (FileNotFoundException fnfe) { - System.err.println("File " + fnfe.getMessage() + " not found."); + System.err.println(Colors.error("File " + fnfe.getMessage() + " not found.")); } catch (ParseException | IOException ex) { - System.err.println(ex.getMessage()); + System.err.println(Colors.error(ex.getMessage())); } catch (CardException ex) { if (logger != null) logger.println(ex.getMessage()); @@ -244,6 +247,7 @@ public class ECTesterReader { * -y / --yes * -ka/ --ka-type <type> * -sig/--sig-type <type> + * -C / --color */ OptionGroup actions = new OptionGroup(); actions.setRequired(true); @@ -300,6 +304,7 @@ public class ECTesterReader { opts.addOption(Option.builder("ka").longOpt("ka-type").desc("Set KeyAgreement object [type], corresponds to JC.KeyAgreement constants.").hasArg().argName("type").optionalArg(true).build()); opts.addOption(Option.builder("sig").longOpt("sig-type").desc("Set Signature object [type], corresponds to JC.Signature constants.").hasArg().argName("type").optionalArg(true).build()); + opts.addOption(Option.builder("C").longOpt("color").desc("Print stuff with color, requires ANSI terminal.").build()); CommandLineParser parser = new DefaultParser(); return parser.parse(opts, args); @@ -318,7 +323,7 @@ public class ECTesterReader { new CardEdgeCasesSuite(null, null, null), new CardTwistTestSuite(null, null, null)}; for (CardTestSuite suite : suites) { - System.out.println(" - " + suite.getName()); + System.out.println(" - " + Colors.bold(suite.getName())); for (String line : suite.getDescription()) { System.out.println("\t" + line); } @@ -396,7 +401,7 @@ public class ECTesterReader { retry++; continue; } else { - System.err.println("Keys could not be generated."); + System.err.println(Colors.error("Keys could not be generated.")); break; } } @@ -471,7 +476,7 @@ public class ECTesterReader { suite = new CardEdgeCasesSuite(writer, cfg, cardManager); break; default: - System.err.println("Unknown test suite."); + System.err.println(Colors.error("Unknown test suite.")); return; } break; @@ -535,7 +540,7 @@ public class ECTesterReader { ++retry; continue; } else { - System.err.println("Couldn't obtain ECDH secret from card response."); + System.err.println(Colors.error("Couldn't obtain ECDH secret from card response.")); break; } } @@ -612,7 +617,7 @@ public class ECTesterReader { ++retry; continue; } else { - System.err.println("Couldn't obtain ECDSA signature from card response."); + System.err.println(Colors.error("Couldn't obtain ECDSA signature from card response.")); break; } } @@ -671,6 +676,7 @@ public class ECTesterReader { public boolean simulate = false; public boolean yes = false; public String format; + public boolean color; //Action-related options public String listNamed; @@ -721,6 +727,8 @@ public class ECTesterReader { fresh = cli.hasOption("fresh"); simulate = cli.hasOption("simulate"); yes = cli.hasOption("yes"); + color = cli.hasOption("color"); + Colors.enabled = color; if (cli.hasOption("list-named")) { listNamed = cli.getOptionValue("list-named"); @@ -730,66 +738,66 @@ public class ECTesterReader { format = cli.getOptionValue("format"); String formats[] = new String[]{"text", "xml", "yaml", "yml"}; if (format != null && !Arrays.asList(formats).contains(format)) { - System.err.println("Wrong output format " + format + ". Should be one of " + Arrays.toString(formats)); + System.err.println(Colors.error("Wrong output format " + format + ". Should be one of " + Arrays.toString(formats))); return false; } if ((key != null || namedKey != null) && (anyPublicKey || anyPrivateKey)) { - System.err.print("Can only specify the whole key with --key/--named-key or pubkey and privkey with --public/--named-public and --private/--named-private."); + System.err.print(Colors.error("Can only specify the whole key with --key/--named-key or pubkey and privkey with --public/--named-public and --private/--named-private.")); return false; } if (bits < 0) { - System.err.println("Bit-size must not be negative."); + System.err.println(Colors.error("Bit-size must not be negative.")); return false; } if (key != null && namedKey != null || publicKey != null && namedPublicKey != null || privateKey != null && namedPrivateKey != null) { - System.err.println("You cannot specify both a named key and a key file."); + System.err.println(Colors.error("You cannot specify both a named key and a key file.")); return false; } if (cli.hasOption("export")) { if (primeField == binaryField) { - System.err.print("Need to specify field with -fp or -f2m. (not both)"); + System.err.print(Colors.error("Need to specify field with -fp or -f2m. (not both)")); return false; } if (anyKeypart) { - System.err.println("Keys should not be specified when exporting curve params."); + System.err.println(Colors.error("Keys should not be specified when exporting curve params.")); return false; } if (namedCurve != null || customCurve || curveFile != null) { - System.err.println("Specifying a curve for curve export makes no sense."); + System.err.println(Colors.error("Specifying a curve for curve export makes no sense.")); return false; } if (outputs == null) { - System.err.println("You have to specify an output file for curve parameter export."); + System.err.println(Colors.error("You have to specify an output file for curve parameter export.")); return false; } if (all || bits == 0) { - System.err.println("You have to specify curve bit-size with -b"); + System.err.println(Colors.error("You have to specify curve bit-size with -b")); return false; } } else if (cli.hasOption("generate")) { if (primeField == binaryField) { - System.err.print("Need to specify field with -fp or -f2m. (not both)"); + System.err.print(Colors.error("Need to specify field with -fp or -f2m. (not both)")); return false; } if (anyKeypart) { - System.err.println("Keys should not be specified when generating keys."); + System.err.println(Colors.error("Keys should not be specified when generating keys.")); return false; } if (outputs == null) { - System.err.println("You have to specify an output file for the key generation process."); + System.err.println(Colors.error("You have to specify an output file for the key generation process.")); return false; } if (all || bits == 0) { - System.err.println("You have to specify curve bit-size with -b"); + System.err.println(Colors.error("You have to specify curve bit-size with -b")); return false; } generateAmount = Integer.parseInt(cli.getOptionValue("generate", "0")); if (generateAmount < 0) { - System.err.println("Amount of keys generated cant be negative."); + System.err.println(Colors.error("Amount of keys generated cant be negative.")); return false; } } else if (cli.hasOption("test")) { @@ -801,44 +809,44 @@ public class ECTesterReader { testSuite = cli.getOptionValue("test", "default").toLowerCase(); String[] tests = new String[]{"default", "composite", "compression", "invalid", "degenerate", "test-vectors", "wrong", "twist", "cofactor", "edge-cases"}; if (!Arrays.asList(tests).contains(testSuite)) { - System.err.println("Unknown test suite " + testSuite + ". Should be one of: " + Arrays.toString(tests)); + System.err.println(Colors.error("Unknown test suite " + testSuite + ". Should be one of: " + Arrays.toString(tests))); return false; } } else if (cli.hasOption("ecdh")) { if (primeField == binaryField) { - System.err.print("Need to specify field with -fp or -f2m. (not both)"); + System.err.print(Colors.error("Need to specify field with -fp or -f2m. (not both)")); return false; } if (all || bits == 0) { - System.err.println("You have to specify curve bit-size with -b"); + System.err.println(Colors.error("You have to specify curve bit-size with -b")); return false; } ECKACount = Integer.parseInt(cli.getOptionValue("ecdh", "1")); if (ECKACount <= 0) { - System.err.println("ECDH count cannot be <= 0."); + System.err.println(Colors.error("ECDH count cannot be <= 0.")); return false; } ECKAType = CardUtil.parseKAType(cli.getOptionValue("ka-type", "1")); } else if (cli.hasOption("ecdsa")) { if (primeField == binaryField) { - System.err.print("Need to specify field with -fp or -f2m. (but not both)"); + System.err.print(Colors.error("Need to specify field with -fp or -f2m. (but not both)")); return false; } if (all || bits == 0) { - System.err.println("You have to specify curve bit-size with -b"); + System.err.println(Colors.error("You have to specify curve bit-size with -b")); return false; } if ((anyPublicKey) != (anyPrivateKey) && !anyKey) { - System.err.println("You cannot only specify a part of a keypair."); + System.err.println(Colors.error("You cannot only specify a part of a keypair.")); return false; } ECDSACount = Integer.parseInt(cli.getOptionValue("ecdsa", "1")); if (ECDSACount <= 0) { - System.err.println("ECDSA count cannot be <= 0."); + System.err.println(Colors.error("ECDSA count cannot be <= 0.")); return false; } |
