From 18bfe2cdac09ff9faed5c92971a7e63d56570ac2 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 4 Feb 2018 18:03:54 +0100 Subject: Add more tests to the Wrong test suite. - Now tests also for: - Fp: - p = 0 - p = 1 - p = q^2; q prime - p = q * s; q and s primes - F2m: - e1 = e2 = e3 = 0 - m < e1 < e2 < e3 --- src/cz/crcs/ectester/reader/command/Command.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/cz/crcs/ectester/reader/command/Command.java') diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 5a6906c..eefbc27 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -374,7 +374,7 @@ public abstract class Command { private byte keyPair; private byte key; private short params; - private byte corruption; + private short corruption; /** * @param cardManager cardManager to send APDU through @@ -383,16 +383,16 @@ public abstract class Command { * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) * @param corruption corruption type (EC_Consts.CORRUPTION_*) */ - public Corrupt(CardMngr cardManager, byte keyPair, byte key, short params, byte corruption) { + public Corrupt(CardMngr cardManager, byte keyPair, byte key, short params, short corruption) { super(cardManager); this.keyPair = keyPair; this.key = key; this.params = params; this.corruption = corruption; - byte[] data = new byte[3]; + byte[] data = new byte[4]; ByteUtil.setShort(data, 0, params); - data[2] = corruption; + ByteUtil.setShort(data, 2, corruption); this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CORRUPT, keyPair, key, data); } -- cgit v1.2.3-70-g09d2 From 22e4cfaf40a259be007bddc7b5cd765390de1c11 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 10 Feb 2018 19:59:41 +0100 Subject: Handle exceptions in Tests and TestSuites grafeully. --- .../ectester/common/output/BaseTextTestWriter.java | 27 ++- .../ectester/common/output/BaseXMLTestWriter.java | 57 ++++- .../ectester/common/output/BaseYAMLTestWriter.java | 21 +- src/cz/crcs/ectester/common/output/TestWriter.java | 17 ++ src/cz/crcs/ectester/common/test/CompoundTest.java | 102 +++++++-- src/cz/crcs/ectester/common/test/Result.java | 6 +- src/cz/crcs/ectester/common/test/SimpleTest.java | 6 + src/cz/crcs/ectester/common/test/Test.java | 44 ++-- .../crcs/ectester/common/test/TestException.java | 7 +- src/cz/crcs/ectester/common/test/TestSuite.java | 22 +- .../ectester/common/test/TestSuiteException.java | 13 ++ src/cz/crcs/ectester/common/test/Testable.java | 2 +- src/cz/crcs/ectester/common/util/CardUtil.java | 14 ++ src/cz/crcs/ectester/reader/ECTesterReader.java | 5 +- src/cz/crcs/ectester/reader/command/Command.java | 241 ++++++++++++++------- .../ectester/reader/output/TextTestWriter.java | 6 +- .../crcs/ectester/reader/output/XMLTestWriter.java | 11 + .../ectester/reader/output/YAMLTestWriter.java | 7 + src/cz/crcs/ectester/reader/response/Response.java | 194 +++-------------- .../ectester/reader/test/CardWrongCurvesSuite.java | 5 +- src/cz/crcs/ectester/reader/test/CommandTest.java | 18 +- .../crcs/ectester/reader/test/CommandTestable.java | 2 +- .../crcs/ectester/reader/test/PerformanceTest.java | 6 +- .../ectester/standalone/ECTesterStandalone.java | 2 +- .../ectester/standalone/test/KeyAgreementTest.java | 10 - .../standalone/test/KeyAgreementTestable.java | 2 +- .../ectester/standalone/test/KeyGeneratorTest.java | 9 - .../standalone/test/KeyGeneratorTestable.java | 2 +- .../ectester/standalone/test/SignatureTest.java | 10 - .../standalone/test/SignatureTestable.java | 2 +- 30 files changed, 491 insertions(+), 379 deletions(-) create mode 100644 src/cz/crcs/ectester/common/test/TestSuiteException.java (limited to 'src/cz/crcs/ectester/reader/command/Command.java') diff --git a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java index 29eb671..f29d28e 100644 --- a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java @@ -28,11 +28,10 @@ public abstract class BaseTextTestWriter implements TestWriter { protected abstract String deviceString(TestSuite suite); private String testString(Test t, String prefix) { - if (!t.hasRun()) { - return null; - } boolean compound = t instanceof CompoundTest; + Result result = t.getResult(); + StringBuilder out = new StringBuilder(); out.append(t.ok() ? " OK " : "NOK "); out.append(compound ? "┳ " : "━ "); @@ -40,14 +39,14 @@ public abstract class BaseTextTestWriter implements TestWriter { String widthSpec = "%-" + String.valueOf(width) + "s"; out.append(String.format(widthSpec, t.getDescription())); out.append(" ┃ "); - out.append(String.format("%-9s", t.getResultValue().name())); + out.append(String.format("%-9s", result.getValue().name())); out.append(" ┃ "); if (compound) { CompoundTest test = (CompoundTest) t; - out.append(test.getResultCause()); + out.append(result.getCause().toString()); out.append(System.lineSeparator()); - Test[] tests = test.getTests(); + Test[] tests = test.getStartedTests(); for (int i = 0; i < tests.length; ++i) { if (i == tests.length - 1) { out.append(prefix).append(" ┗ "); @@ -76,6 +75,22 @@ public abstract class BaseTextTestWriter implements TestWriter { output.flush(); } + private String errorString(Throwable error) { + StringBuilder sb = new StringBuilder(); + for (Throwable t = error; t != null; t = t.getCause()) { + sb.append("═══ ").append(t.toString()).append(" ═══"); + sb.append(System.lineSeparator()); + } + return sb.toString(); + } + + @Override + public void outputError(Test t, Throwable cause) { + output.println(testString(t, "")); + output.print(errorString(cause)); + output.flush(); + } + @Override public void end() { } diff --git a/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java b/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java index f3e9411..5d6d53d 100644 --- a/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java @@ -24,6 +24,7 @@ public abstract class BaseXMLTestWriter implements TestWriter { private DocumentBuilder db; protected Document doc; private Node root; + private Node tests; public BaseXMLTestWriter(OutputStream output) throws ParserConfigurationException { this.output = output; @@ -40,19 +41,55 @@ public abstract class BaseXMLTestWriter implements TestWriter { root = rootElem; doc.appendChild(root); root.appendChild(deviceElement(suite)); + tests = doc.createElement("tests"); + root.appendChild(tests); } protected abstract Element testableElement(Testable t); protected abstract Element deviceElement(TestSuite suite); + private String causeString(Object cause) { + if (cause == null) { + return "null"; + } else if (cause instanceof String) { + return (String) cause; + } else if (cause instanceof Throwable) { + StringBuilder sb = new StringBuilder(); + for (Throwable t = (Throwable) cause; t != null; t = t.getCause()) { + sb.append(t.toString()); + sb.append(System.lineSeparator()); + } + return sb.toString(); + } else { + return cause.toString(); + } + } + + private Element resultElement(Result result) { + Element resultElem = doc.createElement("result"); + + Element ok = doc.createElement("ok"); + ok.setTextContent(String.valueOf(result.ok())); + Element value = doc.createElement("value"); + value.setTextContent(result.getValue().name()); + Element cause = doc.createElement("cause"); + cause.setTextContent(causeString(cause)); + + resultElem.appendChild(ok); + resultElem.appendChild(value); + resultElem.appendChild(cause); + + return resultElem; + } + private Element testElement(Test t) { Element testElem; if (t instanceof CompoundTest) { CompoundTest test = (CompoundTest) t; testElem = doc.createElement("test"); testElem.setAttribute("type", "compound"); - for (Test innerTest : test.getTests()) { + for (Test innerTest : test.getStartedTests()) { testElem.appendChild(testElement(innerTest)); } } else { @@ -64,16 +101,7 @@ public abstract class BaseXMLTestWriter implements TestWriter { description.setTextContent(t.getDescription()); testElem.appendChild(description); - Element result = doc.createElement("result"); - Element ok = doc.createElement("ok"); - ok.setTextContent(String.valueOf(t.ok())); - Element value = doc.createElement("value"); - value.setTextContent(t.getResultValue().name()); - Element cause = doc.createElement("cause"); - cause.setTextContent(t.getResultCause()); - result.appendChild(ok); - result.appendChild(value); - result.appendChild(cause); + Element result = resultElement(t.getResult()); testElem.appendChild(result); return testElem; @@ -83,7 +111,12 @@ public abstract class BaseXMLTestWriter implements TestWriter { public void outputTest(Test t) { if (!t.hasRun()) return; - root.appendChild(testElement(t)); + tests.appendChild(testElement(t)); + } + + @Override + public void outputError(Test t, Throwable cause) { + tests.appendChild(testElement(t)); } @Override diff --git a/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java b/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java index 0769e83..1e13082 100644 --- a/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java @@ -41,6 +41,14 @@ public abstract class BaseYAMLTestWriter implements TestWriter { abstract protected Map deviceObject(TestSuite suite); + private Map resultObject(Result result) { + Map resultObject = new HashMap<>(); + resultObject.put("ok", result.ok()); + resultObject.put("value", result.getValue().name()); + resultObject.put("cause", result.getCause()); + return resultObject; + } + private Map testObject(Test t) { Map testObj; if (t instanceof CompoundTest) { @@ -48,7 +56,7 @@ public abstract class BaseYAMLTestWriter implements TestWriter { testObj = new HashMap<>(); testObj.put("type", "compound"); List> innerTests = new LinkedList<>(); - for (Test innerTest : test.getTests()) { + for (Test innerTest : test.getStartedTests()) { innerTests.add(testObject(innerTest)); } testObj.put("tests", innerTests); @@ -58,11 +66,7 @@ public abstract class BaseYAMLTestWriter implements TestWriter { } testObj.put("desc", t.getDescription()); - Map result = new HashMap<>(); - result.put("ok", t.ok()); - result.put("value", t.getResultValue().name()); - result.put("cause", t.getResultCause()); - testObj.put("result", result); + testObj.put("result", resultObject(t.getResult())); return testObj; } @@ -74,6 +78,11 @@ public abstract class BaseYAMLTestWriter implements TestWriter { tests.add(testObject(t)); } + @Override + public void outputError(Test t, Throwable cause) { + tests.add(testObject(t)); + } + @Override public void end() { DumperOptions options = new DumperOptions(); diff --git a/src/cz/crcs/ectester/common/output/TestWriter.java b/src/cz/crcs/ectester/common/output/TestWriter.java index 0ecfd5a..5fa7f67 100644 --- a/src/cz/crcs/ectester/common/output/TestWriter.java +++ b/src/cz/crcs/ectester/common/output/TestWriter.java @@ -7,9 +7,26 @@ import cz.crcs.ectester.common.test.TestSuite; * @author Jan Jancar johny@neuromancer.sk */ public interface TestWriter { + /** + * @param suite + */ void begin(TestSuite suite); + /** + * + * @param t + */ void outputTest(Test t); + /** + * + * @param t + * @param cause + */ + void outputError(Test t, Throwable cause); + + /** + * + */ void end(); } diff --git a/src/cz/crcs/ectester/common/test/CompoundTest.java b/src/cz/crcs/ectester/common/test/CompoundTest.java index 69122b0..4b1df16 100644 --- a/src/cz/crcs/ectester/common/test/CompoundTest.java +++ b/src/cz/crcs/ectester/common/test/CompoundTest.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.common.test; import java.util.Arrays; import java.util.Objects; +import java.util.function.Consumer; import java.util.function.Function; /** @@ -10,26 +11,34 @@ import java.util.function.Function; * @author Jan Jancar johny@neuromancer.sk */ public class CompoundTest extends Test { - private Function callback; + private Function resultCallback; + private Consumer runCallback; private Test[] tests; private String description = ""; - private CompoundTest(Function callback, Test... tests) { - this.callback = callback; + private final static Consumer RUN_ALL = tests -> { + for (Test t : tests) { + t.run(); + } + }; + + private CompoundTest(Function resultCallback, Consumer runCallback, Test... tests) { + this.resultCallback = resultCallback; + this.runCallback = runCallback; this.tests = Arrays.stream(tests).filter(Objects::nonNull).toArray(Test[]::new); } - private CompoundTest(Function callback, String descripiton, Test... tests) { - this(callback, tests); + private CompoundTest(Function callback, Consumer runCallback, String descripiton, Test... tests) { + this(callback, runCallback, tests); this.description = descripiton; } public static CompoundTest function(Function callback, Test... tests) { - return new CompoundTest(callback, tests); + return new CompoundTest(callback, RUN_ALL, tests); } public static CompoundTest function(Function callback, String description, Test... tests) { - return new CompoundTest(callback, description, tests); + return new CompoundTest(callback, RUN_ALL, description, tests); } public static CompoundTest all(Result.ExpectedValue what, Test... all) { @@ -40,7 +49,7 @@ public class CompoundTest extends Test { } } return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result."); - }, all); + }, RUN_ALL, all); } public static CompoundTest all(Result.ExpectedValue what, String description, Test... all) { @@ -49,7 +58,31 @@ public class CompoundTest extends Test { return result; } - public static CompoundTest any(Result.ExpectedValue what, Test... any) { + public static CompoundTest greedyAll(Result.ExpectedValue what, Test... all) { + return new CompoundTest((tests) -> { + for (Test test : tests) { + if (!Result.Value.fromExpected(what, test.ok()).ok()) { + return new Result(Result.Value.FAILURE, "Some sub-tests did not have the expected result."); + } + } + return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result."); + }, (tests) -> { + for (Test t : tests) { + t.run(); + if (!t.ok()) { + break; + } + } + }, all); + } + + public static CompoundTest greedyAll(Result.ExpectedValue what, String description, Test... all) { + CompoundTest result = CompoundTest.greedyAll(what, all); + result.setDescription(description); + return result; + } + + public static CompoundTest greedyAny(Result.ExpectedValue what, Test... any) { return new CompoundTest((tests) -> { for (Test test : tests) { if (Result.Value.fromExpected(what, test.ok()).ok()) { @@ -57,9 +90,33 @@ public class CompoundTest extends Test { } } return new Result(Result.Value.FAILURE, "None of the sub-tests had the expected result."); + }, (tests) -> { + for (Test t : tests) { + t.run(); + if (t.ok()) { + break; + } + } }, any); } + public static CompoundTest greedyAny(Result.ExpectedValue what, String description, Test... any) { + CompoundTest result = CompoundTest.greedyAny(what, any); + result.setDescription(description); + return result; + } + + public static CompoundTest any(Result.ExpectedValue what, Test... any) { + return new CompoundTest((tests) -> { + for (Test test : tests) { + if (Result.Value.fromExpected(what, test.ok()).ok()) { + return new Result(Result.Value.SUCCESS, "Some sub-tests did have the expected result."); + } + } + return new Result(Result.Value.FAILURE, "None of the sub-tests had the expected result."); + }, RUN_ALL, any); + } + public static CompoundTest any(Result.ExpectedValue what, String description, Test... any) { CompoundTest result = CompoundTest.any(what, any); result.setDescription(description); @@ -74,7 +131,7 @@ public class CompoundTest extends Test { } } return new Result(Result.Value.SUCCESS, "All sub-tests matched the expected mask."); - }, masked); + }, RUN_ALL, masked); } public static CompoundTest mask(Result.ExpectedValue[] results, String description, Test... masked) { @@ -84,20 +141,25 @@ public class CompoundTest extends Test { } public Test[] getTests() { - return tests; + return tests.clone(); } - @Override - public void run() throws TestException { - if (hasRun) - return; + public Test[] getRunTests() { + return Arrays.stream(tests).filter(Test::hasRun).toArray(Test[]::new); + } - for (Test test : tests) { - test.run(); - } + public Test[] getStartedTests() { + return Arrays.stream(tests).filter(Test::hasStarted).toArray(Test[]::new); + } - result = callback.apply(tests); - this.hasRun = true; + public Test[] getSkippedTests() { + return Arrays.stream(tests).filter((test) -> !test.hasRun()).toArray(Test[]::new); + } + + @Override + protected void runSelf() { + runCallback.accept(tests); + result = resultCallback.apply(tests); } public void setDescription(String description) { diff --git a/src/cz/crcs/ectester/common/test/Result.java b/src/cz/crcs/ectester/common/test/Result.java index 11fcb4d..5d15a60 100644 --- a/src/cz/crcs/ectester/common/test/Result.java +++ b/src/cz/crcs/ectester/common/test/Result.java @@ -8,13 +8,13 @@ package cz.crcs.ectester.common.test; public class Result { private Value value; - private String cause; + private Object cause; public Result(Value value) { this.value = value; } - public Result(Value value, String cause) { + public Result(Value value, Object cause) { this(value); this.cause = cause; } @@ -23,7 +23,7 @@ public class Result { return value; } - public String getCause() { + public Object getCause() { return cause; } diff --git a/src/cz/crcs/ectester/common/test/SimpleTest.java b/src/cz/crcs/ectester/common/test/SimpleTest.java index f68320a..85f1072 100644 --- a/src/cz/crcs/ectester/common/test/SimpleTest.java +++ b/src/cz/crcs/ectester/common/test/SimpleTest.java @@ -16,4 +16,10 @@ public abstract class SimpleTest extends Test { public T getTestable() { return testable; } + + @Override + protected void runSelf() { + testable.run(); + result = callback.apply(testable); + } } diff --git a/src/cz/crcs/ectester/common/test/Test.java b/src/cz/crcs/ectester/common/test/Test.java index 3d0baf6..868fd22 100644 --- a/src/cz/crcs/ectester/common/test/Test.java +++ b/src/cz/crcs/ectester/common/test/Test.java @@ -9,31 +9,15 @@ import static cz.crcs.ectester.common.test.Result.Value; */ public abstract class Test implements Testable { protected boolean hasRun; + protected boolean hasStarted; protected Result result; public Result getResult() { - if (!hasRun) { - return null; - } return result; } - public Value getResultValue() { - if (!hasRun) { - return null; - } - return result.getValue(); - } - - public String getResultCause() { - if (!hasRun) { - return null; - } - return result.getCause(); - } - public boolean ok() { - if (!hasRun) { + if (result == null) { return true; } return result.ok(); @@ -41,7 +25,7 @@ public abstract class Test implements Testable { @Override public boolean error() { - if (!hasRun) { + if (result == null) { return false; } return result.compareTo(Value.ERROR); @@ -52,15 +36,35 @@ public abstract class Test implements Testable { return hasRun; } + public boolean hasStarted() { + return hasStarted; + } + @Override public void reset() { hasRun = false; + hasStarted = false; result = null; } public abstract String getDescription(); @Override - public abstract void run() throws TestException; + public void run() { + if (hasRun) + return; + try { + hasStarted = true; + runSelf(); + hasRun = true; + } catch (TestException e) { + result = new Result(Value.ERROR, e); + throw e; + } catch (Exception e) { + result = new Result(Value.ERROR, e); + throw new TestException(e); + } + } + protected abstract void runSelf(); } diff --git a/src/cz/crcs/ectester/common/test/TestException.java b/src/cz/crcs/ectester/common/test/TestException.java index 008e9f6..291a073 100644 --- a/src/cz/crcs/ectester/common/test/TestException.java +++ b/src/cz/crcs/ectester/common/test/TestException.java @@ -2,11 +2,12 @@ package cz.crcs.ectester.common.test; /** * A TestException is an Exception that can be thrown during the running of a Testable, - * or a TestSuite. It means that the Testable/TestSuite encountered an unexpected error - * during it's run which points to an error in ECTester or it's runtime environment.cd + * or a Test. It means that the Testable/TestSuite encountered an unexpected error + * and has to terminate. + * * @author Jan Jancar johny@neuromancer.sk */ -public class TestException extends Exception { +public class TestException extends RuntimeException { public TestException(Throwable e) { super(e); } diff --git a/src/cz/crcs/ectester/common/test/TestSuite.java b/src/cz/crcs/ectester/common/test/TestSuite.java index 2de0b9c..ca1b199 100644 --- a/src/cz/crcs/ectester/common/test/TestSuite.java +++ b/src/cz/crcs/ectester/common/test/TestSuite.java @@ -9,6 +9,7 @@ public abstract class TestSuite { protected String name; protected String description; protected TestWriter writer; + private Test running; public TestSuite(TestWriter writer, String name, String description) { this.writer = writer; @@ -16,12 +17,18 @@ public abstract class TestSuite { this.description = description; } - public void run() throws TestException { + /** + * + */ + public void run() { writer.begin(this); try { runTests(); + } catch (TestException e) { + writer.outputError(running, e); } catch (Exception e) { - throw new TestException(e); + writer.end(); + throw new TestSuiteException(e); } writer.end(); } @@ -33,8 +40,10 @@ public abstract class TestSuite { * @return The test that was run. * @throws TestException */ - protected Test runTest(Test t) throws TestException { + protected Test runTest(Test t) { + running = t; t.run(); + running = null; return t; } @@ -45,12 +54,15 @@ public abstract class TestSuite { * @return The test that was run. * @throws TestException */ - protected Test doTest(Test t) throws TestException { - t.run(); + protected Test doTest(Test t) { + runTest(t); writer.outputTest(t); return t; } + /** + * + */ protected abstract void runTests() throws Exception; public String getName() { diff --git a/src/cz/crcs/ectester/common/test/TestSuiteException.java b/src/cz/crcs/ectester/common/test/TestSuiteException.java new file mode 100644 index 0000000..cc3cfda --- /dev/null +++ b/src/cz/crcs/ectester/common/test/TestSuiteException.java @@ -0,0 +1,13 @@ +package cz.crcs.ectester.common.test; + +/** + * An unexpected exception was thrown while running a TestSuite, outside Test + * or a Testable. + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class TestSuiteException extends RuntimeException { + public TestSuiteException(Throwable e) { + super(e); + } +} diff --git a/src/cz/crcs/ectester/common/test/Testable.java b/src/cz/crcs/ectester/common/test/Testable.java index 33c9485..ea1380a 100644 --- a/src/cz/crcs/ectester/common/test/Testable.java +++ b/src/cz/crcs/ectester/common/test/Testable.java @@ -29,5 +29,5 @@ public interface Testable { * * @throws TestException If an unexpected exception/error is encountered. */ - void run() throws TestException; + void run(); } diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java index dbe53be..7d7bb78 100644 --- a/src/cz/crcs/ectester/common/util/CardUtil.java +++ b/src/cz/crcs/ectester/common/util/CardUtil.java @@ -281,4 +281,18 @@ public class CardUtil { return ""; } } + + public static String getParameterString(short params) { + String what = ""; + if (params == EC_Consts.PARAMETERS_DOMAIN_F2M || params == EC_Consts.PARAMETERS_DOMAIN_FP) { + what = "curve"; + } else if (params == EC_Consts.PARAMETER_W) { + what = "pubkey"; + } else if (params == EC_Consts.PARAMETER_S) { + what = "privkey"; + } else if (params == EC_Consts.PARAMETERS_KEYPAIR) { + what = "keypair"; + } + return what; + } } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index e05f9be..22621ef 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -179,7 +179,7 @@ public class ECTesterReader { System.err.println("File " + fnfe.getMessage() + " not found."); } catch (ParseException | IOException ex) { System.err.println(ex.getMessage()); - } catch (CardException | TestException ex) { + } catch (CardException ex) { if (logger != null) logger.println(ex.getMessage()); ex.printStackTrace(); @@ -394,10 +394,9 @@ public class ECTesterReader { /** * Tests Elliptic curve support for a given curve/curves. * - * @throws CardException if APDU transmission fails * @throws IOException if an IO error occurs when writing to key file. */ - private void test() throws IOException, TestException, ParserConfigurationException { + private void test() throws IOException, ParserConfigurationException { TestWriter writer = null; if (cfg.format == null) { writer = new TextTestWriter(logger.getPrintStream()); diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index eefbc27..5e025d8 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -2,15 +2,16 @@ package cz.crcs.ectester.reader.command; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import cz.crcs.ectester.common.ec.EC_Keypair; +import cz.crcs.ectester.common.ec.EC_Params; import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.common.util.CardUtil; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; -import cz.crcs.ectester.common.ec.EC_Keypair; -import cz.crcs.ectester.common.ec.EC_Params; import javacard.security.KeyPair; import javax.smartcardio.CardException; @@ -46,6 +47,8 @@ public abstract class Command { return result; } + public abstract String getDescription(); + /** * @param keyPair which keyPair/s (local/remote) to set curve domain parameters on @@ -179,111 +182,117 @@ public abstract class Command { return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, params, data); } - /** * */ - public static class Allocate extends Command { - private byte keyPair; - private short keyLength; - private byte keyClass; + public static class AllocateKeyAgreement extends Command { + private byte kaType; /** - * Creates the INS_ALLOCATE instruction. + * Creates the INS_ALLOCATE_KA instruction. * * @param cardManager cardManager to send APDU through - * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) - * @param keyLength key length to set - * @param keyClass key class to allocate + * @param kaType which type of KeyAgreement to use */ - public Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) { + public AllocateKeyAgreement(CardMngr cardManager, byte kaType) { super(cardManager); - this.keyPair = keyPair; - this.keyLength = keyLength; - this.keyClass = keyClass; - - byte[] data = new byte[]{0, 0, keyClass}; - ByteUtil.setShort(data, 0, keyLength); - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data); + this.kaType = kaType; + byte[] data = new byte[]{kaType}; + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_KA, 0x00, 0x00, data); } @Override - public Response.Allocate send() throws CardException { + public Response.AllocateKeyAgreement send() throws CardException { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Allocate(response, elapsed, keyPair, keyLength, keyClass); + return new Response.AllocateKeyAgreement(response, getDescription(), elapsed, kaType); } @Override - public String toString() { - return "Allocate"; + public String getDescription() { + return String.format("Allocate KeyAgreement(%s) object", CardUtil.getKATypeString(kaType)); } } /** * */ - public static class AllocateKeyAgreement extends Command { - private byte kaType; + public static class AllocateSignature extends Command { + private byte sigType; /** - * Creates the INS_ALLOCATE_KA instruction. + * Creates the INS_ALLOCATE_SIG instruction. * * @param cardManager cardManager to send APDU through - * @param kaType which type of KeyAgreement to use + * @param sigType which type of Signature to use */ - public AllocateKeyAgreement(CardMngr cardManager, byte kaType) { + public AllocateSignature(CardMngr cardManager, byte sigType) { super(cardManager); - this.kaType = kaType; - byte[] data = new byte[]{kaType}; - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_KA, 0x00, 0x00, data); + this.sigType = sigType; + byte[] data = new byte[]{sigType}; + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_SIG, 0x00, 0x00, data); } @Override - public Response.AllocateKeyAgreement send() throws CardException { + public Response.AllocateSignature send() throws CardException { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.AllocateKeyAgreement(response, elapsed, kaType); + return new Response.AllocateSignature(response, getDescription(), elapsed, sigType); } @Override - public String toString() { - return "AllocateKeyAgreement"; + public String getDescription() { + return String.format("Allocate Signature(%s) object", CardUtil.getSigTypeString(sigType)); } } /** * */ - public static class AllocateSignature extends Command { - private byte sigType; + public static class Allocate extends Command { + private byte keyPair; + private short keyLength; + private byte keyClass; /** - * Creates the INS_ALLOCATE_SIG instruction. + * Creates the INS_ALLOCATE instruction. * * @param cardManager cardManager to send APDU through - * @param sigType which type of Signature to use + * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) + * @param keyLength key length to set + * @param keyClass key class to allocate */ - public AllocateSignature(CardMngr cardManager, byte sigType) { + public Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) { super(cardManager); - this.sigType = sigType; - byte[] data = new byte[]{sigType}; - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_SIG, 0x00, 0x00, data); + this.keyPair = keyPair; + this.keyLength = keyLength; + this.keyClass = keyClass; + + byte[] data = new byte[]{0, 0, keyClass}; + ByteUtil.setShort(data, 0, keyLength); + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data); } @Override - public Response.AllocateSignature send() throws CardException { + public Response.Allocate send() throws CardException { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.AllocateSignature(response, elapsed, sigType); + return new Response.Allocate(response, getDescription(), elapsed, keyPair, keyLength, keyClass); } @Override - public String toString() { - return "AllocateSignature"; + public String getDescription() { + String field = keyClass == KeyPair.ALG_EC_FP ? "ALG_EC_FP" : "ALG_EC_F2M"; + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return String.format("Allocate %s %db %s", key, keyLength, field); } } @@ -309,12 +318,18 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Clear(response, elapsed, keyPair); + return new Response.Clear(response, getDescription(), elapsed, keyPair); } @Override - public String toString() { - return "Clear"; + public String getDescription() { + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return String.format("Clear %s", key); } } @@ -358,12 +373,32 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Set(response, elapsed, keyPair, curve, params); + return new Response.Set(response, getDescription(), elapsed, keyPair, curve, params); } @Override - public String toString() { - return "Set"; + public String getDescription() { + String name; + switch (curve) { + case EC_Consts.CURVE_default: + name = "default"; + break; + case EC_Consts.CURVE_external: + name = "external"; + break; + default: + name = "custom"; + break; + } + String what = CardUtil.getParameterString(params); + + String pair; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + pair = "both keypairs"; + } else { + pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return String.format("Set %s %s parameters on %s", name, what, pair); } } @@ -402,12 +437,20 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Corrupt(response, elapsed, keyPair, key, params, corruption); + return new Response.Corrupt(response, getDescription(), elapsed, keyPair, key, params, corruption); } @Override - public String toString() { - return "Corrupt"; + public String getDescription() { + String corrupt = CardUtil.getCorruption(corruption); + + String pair; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + pair = "both keypairs"; + } else { + pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return String.format("Corrupt params of %s, %s", pair, corrupt); } } @@ -435,12 +478,18 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Generate(response, elapsed, keyPair); + return new Response.Generate(response, getDescription(), elapsed, keyPair); } @Override - public String toString() { - return "Generate"; + public String getDescription() { + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return String.format("Generate %s", key); } } @@ -477,12 +526,26 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Export(response, elapsed, keyPair, key, params); + return new Response.Export(response, getDescription(), elapsed, keyPair, key, params); } @Override - public String toString() { - return "Export"; + public String getDescription() { + String what = CardUtil.getParameterString(params); + + String source; + if (key == EC_Consts.KEY_BOTH) { + source = "both keys"; + } else { + source = ((key == EC_Consts.KEY_PUBLIC) ? "public" : "private") + " key"; + } + String pair; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + pair = "both keypairs"; + } else { + pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return String.format("Export %s params from %s of %s", what, source, pair); } } @@ -514,7 +577,7 @@ public abstract class Command { this.corruption = corruption; this.type = type; - byte[] data = new byte[]{export, 0,0, type}; + byte[] data = new byte[]{export, 0, 0, type}; ByteUtil.setShort(data, 1, corruption); this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); @@ -525,12 +588,23 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDH(response, elapsed, pubkey, privkey, export, corruption, type); + return new Response.ECDH(response, getDescription(), elapsed, pubkey, privkey, export, corruption, type); } @Override - public String toString() { - return "ECDH"; + public String getDescription() { + String algo = CardUtil.getKATypeString(type); + + String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + + String validity; + if (corruption == EC_Consts.CORRUPTION_NONE) { + validity = "unchanged"; + } else { + validity = CardUtil.getCorruption(corruption); + } + return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity); } } @@ -575,12 +649,22 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDH(response, elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, corruption, type); + return new Response.ECDH(response, getDescription(), elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, corruption, type); } @Override - public String toString() { - return "ECDH_direct"; + public String getDescription() { + String algo = CardUtil.getKATypeString(type); + + String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + + String validity; + if (corruption == EC_Consts.CORRUPTION_NONE) { + validity = "unchanged"; + } else { + validity = CardUtil.getCorruption(corruption); + } + return String.format("%s of external pubkey and %s privkey(%s point)", algo, priv, validity); } } @@ -622,12 +706,15 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDSA(response, elapsed, keyPair, sigType, export, raw); + return new Response.ECDSA(response, getDescription(), elapsed, keyPair, sigType, export, raw); } @Override - public String toString() { - return "ECDSA"; + public String getDescription() { + String algo = CardUtil.getSigTypeString(sigType); + String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String data = raw == null ? "random" : "provided"; + return String.format("%s with %s keypair(%s data)", algo, key, data); } } @@ -650,12 +737,12 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Cleanup(response, elapsed); + return new Response.Cleanup(response, getDescription(), elapsed); } @Override - public String toString() { - return "Cleanup"; + public String getDescription() { + return "Request JCSystem object deletion"; } } } diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index eb52937..cc168de 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -5,6 +5,7 @@ import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.test.Testable; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.CardTestSuite; import cz.crcs.ectester.reader.test.CommandTestable; @@ -27,7 +28,10 @@ public class TextTestWriter extends BaseTextTestWriter { protected String testableString(Testable t) { if (t instanceof CommandTestable) { CommandTestable cmd = (CommandTestable) t; - return writer.responseSuffix(cmd.getResponse()); + Response response = cmd.getResponse(); + if (response != null) { + return writer.responseSuffix(response); + } } return ""; } diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index d3674e8..ebe07a6 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -26,16 +26,27 @@ public class XMLTestWriter extends BaseXMLTestWriter { private Element commandElement(Command c) { Element commandElem = doc.createElement("command"); + if (c == null) { + return commandElem; + } Element apdu = doc.createElement("apdu"); apdu.setTextContent(ByteUtil.bytesToHex(c.getAPDU().getBytes())); commandElem.appendChild(apdu); + Element description = doc.createElement("desc"); + description.setTextContent(c.getDescription()); + commandElem.appendChild(description); + return commandElem; } private Element responseElement(Response r) { Element responseElem = doc.createElement("response"); + if (r == null) { + return responseElem; + } + responseElem.setAttribute("successful", r.successful() ? "true" : "false"); Element apdu = doc.createElement("apdu"); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index 199f2c0..4f83ca8 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -27,12 +27,19 @@ public class YAMLTestWriter extends BaseYAMLTestWriter { private Map commandObject(Command c) { Map commandObj = new HashMap<>(); + if (c == null) { + return commandObj; + } commandObj.put("apdu", ByteUtil.bytesToHex(c.getAPDU().getBytes())); + commandObj.put("desc", c.getDescription()); return commandObj; } private Map responseObject(Response r) { Map responseObj = new HashMap<>(); + if (r == null) { + return responseObj; + } responseObj.put("successful", r.successful()); responseObj.put("apdu", ByteUtil.bytesToHex(r.getAPDU().getBytes())); responseObj.put("natural_sw", Short.toUnsignedInt(r.getNaturalSW())); diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 1ae59de..5a9a458 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -3,9 +3,7 @@ package cz.crcs.ectester.reader.response; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.util.ByteUtil; -import cz.crcs.ectester.common.util.CardUtil; import javacard.framework.ISO7816; -import javacard.security.KeyPair; import javax.smartcardio.ResponseAPDU; @@ -20,9 +18,11 @@ public abstract class Response { private byte[][] params; private boolean success = true; private boolean error = false; + private String description; - public Response(ResponseAPDU response, long time) { + public Response(ResponseAPDU response, String description, long time) { this.resp = response; + this.description = description; this.time = time; } @@ -127,7 +127,9 @@ public abstract class Response { return this.error; } - public abstract String getDescription(); + public String getDescription() { + return description; + } /** * @@ -135,17 +137,12 @@ public abstract class Response { public static class AllocateKeyAgreement extends Response { private byte kaType; - public AllocateKeyAgreement(ResponseAPDU response, long time, byte kaType) { - super(response, time); + public AllocateKeyAgreement(ResponseAPDU response, String description, long time, byte kaType) { + super(response, description, time); this.kaType = kaType; parse(1, 0); } - - @Override - public String getDescription() { - return String.format("Allocated KeyAgreement(%s) object", CardUtil.getKATypeString(this.kaType)); - } } /** @@ -154,17 +151,12 @@ public abstract class Response { public static class AllocateSignature extends Response { private byte sigType; - public AllocateSignature(ResponseAPDU response, long time, byte sigType) { - super(response, time); + public AllocateSignature(ResponseAPDU response, String description, long time, byte sigType) { + super(response, description, time); this.sigType = sigType; parse(1, 0); } - - @Override - public String getDescription() { - return String.format("Allocated Signature(%s) object", CardUtil.getSigTypeString(this.sigType)); - } } /** @@ -175,8 +167,8 @@ public abstract class Response { private short keyLength; private byte keyClass; - public Allocate(ResponseAPDU response, long time, byte keyPair, short keyLength, byte keyClass) { - super(response, time); + public Allocate(ResponseAPDU response, String description, long time, byte keyPair, short keyLength, byte keyClass) { + super(response, description, time); this.keyPair = keyPair; this.keyLength = keyLength; this.keyClass = keyClass; @@ -186,18 +178,6 @@ public abstract class Response { if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; parse(pairs, 0); } - - @Override - public String getDescription() { - String field = keyClass == KeyPair.ALG_EC_FP ? "ALG_EC_FP" : "ALG_EC_F2M"; - String key; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - key = "both keypairs"; - } else { - key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return String.format("Allocated %s %db %s", key, keyLength, field); - } } /** @@ -206,8 +186,8 @@ public abstract class Response { public static class Clear extends Response { private byte keyPair; - public Clear(ResponseAPDU response, long time, byte keyPair) { - super(response, time); + public Clear(ResponseAPDU response, String description, long time, byte keyPair) { + super(response, description, time); this.keyPair = keyPair; int pairs = 0; @@ -215,17 +195,6 @@ public abstract class Response { if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; parse(pairs, 0); } - - @Override - public String getDescription() { - String key; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - key = "both keypairs"; - } else { - key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return String.format("Cleared %s", key); - } } /** @@ -236,8 +205,8 @@ public abstract class Response { private byte curve; private short parameters; - public Set(ResponseAPDU response, long time, byte keyPair, byte curve, short parameters) { - super(response, time); + public Set(ResponseAPDU response, String description, long time, byte keyPair, byte curve, short parameters) { + super(response, description, time); this.keyPair = keyPair; this.curve = curve; this.parameters = parameters; @@ -248,41 +217,6 @@ public abstract class Response { parse(pairs, 0); } - - @Override - public String getDescription() { - String name; - switch (curve) { - case EC_Consts.CURVE_default: - name = "default"; - break; - case EC_Consts.CURVE_external: - name = "external"; - break; - default: - name = "custom"; - break; - } - String what = ""; - if (parameters == EC_Consts.PARAMETERS_DOMAIN_F2M || parameters == EC_Consts.PARAMETERS_DOMAIN_FP) { - what = "curve"; - } else if (parameters == EC_Consts.PARAMETER_W) { - what = "pubkey"; - } else if (parameters == EC_Consts.PARAMETER_S) { - what = "privkey"; - } else if (parameters == EC_Consts.PARAMETERS_KEYPAIR) { - what = "keypair"; - } - - String pair; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - pair = "both keypairs"; - } else { - pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return String.format("Set %s %s parameters on %s", name, what, pair); - } - } /** @@ -294,8 +228,8 @@ public abstract class Response { private short params; private short corruption; - public Corrupt(ResponseAPDU response, long time, byte keyPair, byte key, short params, short corruption) { - super(response, time); + public Corrupt(ResponseAPDU response, String description, long time, byte keyPair, byte key, short params, short corruption) { + super(response, description, time); this.keyPair = keyPair; this.key = key; this.params = params; @@ -307,19 +241,6 @@ public abstract class Response { parse(pairs, 0); } - - @Override - public String getDescription() { - String corrupt = CardUtil.getCorruption(corruption); - - String pair; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - pair = "both keypairs"; - } else { - pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return String.format("Corrupted params of %s, %s", pair, corrupt); - } } /** @@ -328,8 +249,8 @@ public abstract class Response { public static class Generate extends Response { private byte keyPair; - public Generate(ResponseAPDU response, long time, byte keyPair) { - super(response, time); + public Generate(ResponseAPDU response, String description, long time, byte keyPair) { + super(response, description, time); this.keyPair = keyPair; int generated = 0; @@ -337,18 +258,6 @@ public abstract class Response { if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) generated++; parse(generated, 0); } - - @Override - public String getDescription() { - String key; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - key = "both keypairs"; - } else { - key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return String.format("Generated %s", key); - } - } /** @@ -359,8 +268,8 @@ public abstract class Response { private byte key; private short parameters; - public Export(ResponseAPDU response, long time, byte keyPair, byte key, short parameters) { - super(response, time); + public Export(ResponseAPDU response, String description, long time, byte keyPair, byte key, short parameters) { + super(response, description, time); this.keyPair = keyPair; this.key = key; this.parameters = parameters; @@ -440,23 +349,6 @@ public abstract class Response { public byte[] getParameter(byte keyPair, short param) { return getParam(getIndex(keyPair, param)); } - - @Override - public String getDescription() { - String source; - if (key == EC_Consts.KEY_BOTH) { - source = "both keys"; - } else { - source = ((key == EC_Consts.KEY_PUBLIC) ? "public" : "private") + " key"; - } - String pair; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - pair = "both keypairs"; - } else { - pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return String.format("Exported params from %s of %s", source, pair); - } } /** @@ -469,8 +361,8 @@ public abstract class Response { private short corruption; private byte type; - public ECDH(ResponseAPDU response, long time, byte pubkey, byte privkey, byte export, short corruption, byte type) { - super(response, time); + public ECDH(ResponseAPDU response, String description, long time, byte pubkey, byte privkey, byte export, short corruption, byte type) { + super(response, description, time); this.pubkey = pubkey; this.privkey = privkey; this.export = export; @@ -491,22 +383,6 @@ public abstract class Response { public int secretLength() { return getParamLength(0); } - - @Override - public String getDescription() { - String algo = CardUtil.getKATypeString(type); - - String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; - String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; - - String validity; - if (corruption == EC_Consts.CORRUPTION_NONE) { - validity = "unchanged"; - } else { - validity = CardUtil.getCorruption(corruption); - } - return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity); - } } /** @@ -518,8 +394,8 @@ public abstract class Response { private byte export; private byte[] raw; - public ECDSA(ResponseAPDU response, long time, byte keyPair, byte sigType, byte export, byte[] raw) { - super(response, time); + public ECDSA(ResponseAPDU response, String description, long time, byte keyPair, byte sigType, byte export, byte[] raw) { + super(response, description, time); this.keyPair = keyPair; this.sigType = sigType; this.export = export; @@ -535,14 +411,6 @@ public abstract class Response { public byte[] getSignature() { return getParam(0); } - - @Override - public String getDescription() { - String algo = CardUtil.getSigTypeString(sigType); - String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; - String data = raw == null ? "random" : "provided"; - return String.format("%s with %s keypair(%s data)", algo, key, data); - } } /** @@ -550,16 +418,10 @@ public abstract class Response { */ public static class Cleanup extends Response { - public Cleanup(ResponseAPDU response, long time) { - super(response, time); + public Cleanup(ResponseAPDU response, String description, long time) { + super(response, description, time); parse(1, 0); } - - @Override - public String getDescription() { - return "Requested JCSystem object deletion"; - } - } } diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 1c3ad94..4706bdd 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -8,7 +8,6 @@ import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestException; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.common.util.CardUtil; import cz.crcs.ectester.common.util.ECUtil; @@ -44,7 +43,7 @@ public class CardWrongCurvesSuite extends CardTestSuite { List tests = new LinkedList<>(); Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); if (!key.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), key)); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), key)); continue; } tests.add(key); @@ -143,7 +142,7 @@ public class CardWrongCurvesSuite extends CardTestSuite { */ } - private Test ecdhTest(Command setupCmd, String prepareDesc, String fullDesc) throws TestException { + private Test ecdhTest(Command setupCmd, String prepareDesc, String fullDesc) { Test setup = runTest(CommandTest.expect(setupCmd, Result.ExpectedValue.FAILURE)); Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.FAILURE)); Test preparePhase = runTest(CompoundTest.any(Result.ExpectedValue.SUCCESS, prepareDesc, setup, generate)); diff --git a/src/cz/crcs/ectester/reader/test/CommandTest.java b/src/cz/crcs/ectester/reader/test/CommandTest.java index a08d820..d57dc17 100644 --- a/src/cz/crcs/ectester/reader/test/CommandTest.java +++ b/src/cz/crcs/ectester/reader/test/CommandTest.java @@ -3,13 +3,14 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.SimpleTest; import cz.crcs.ectester.common.test.TestCallback; -import cz.crcs.ectester.common.test.TestException; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; /** * A simple test that runs one Command to get and evaluate one Response * to get a Result and compare it with the expected one. + * + * @author Jan Jancar johny@neuromancer.sk */ public class CommandTest extends SimpleTest { private CommandTest(CommandTestable command, TestCallback callback) { @@ -28,8 +29,7 @@ public class CommandTest extends SimpleTest { return new CommandTest(command, new TestCallback() { @Override public Result apply(CommandTestable commandTestable) { - Response resp = commandTestable.getResponse(); - Result.Value resultValue = Result.Value.fromExpected(expected, resp.successful(), resp.error()); + Result.Value resultValue = Result.Value.fromExpected(expected, commandTestable.ok(), commandTestable.error()); return new Result(resultValue, resultValue.ok() ? ok : nok); } }); @@ -55,22 +55,12 @@ public class CommandTest extends SimpleTest { return testable.getResponse(); } - @Override - public void run() throws TestException { - if (hasRun) - return; - - testable.run(); - result = callback.apply(testable); - hasRun = true; - } - @Override public String getDescription() { if (hasRun) { return testable.getResponse().getDescription(); } else { - return testable.getCommand().toString(); + return testable.getCommand().getDescription(); } } } diff --git a/src/cz/crcs/ectester/reader/test/CommandTestable.java b/src/cz/crcs/ectester/reader/test/CommandTestable.java index 3bb55bf..f670534 100644 --- a/src/cz/crcs/ectester/reader/test/CommandTestable.java +++ b/src/cz/crcs/ectester/reader/test/CommandTestable.java @@ -27,7 +27,7 @@ public class CommandTestable extends BaseTestable { } @Override - public void run() throws TestException { + public void run() { try { response = command.send(); } catch (CardException e) { diff --git a/src/cz/crcs/ectester/reader/test/PerformanceTest.java b/src/cz/crcs/ectester/reader/test/PerformanceTest.java index 4a27bad..2e5f376 100644 --- a/src/cz/crcs/ectester/reader/test/PerformanceTest.java +++ b/src/cz/crcs/ectester/reader/test/PerformanceTest.java @@ -38,10 +38,7 @@ public class PerformanceTest extends SimpleTest { } @Override - public void run() throws TestException { - if (hasRun) - return; - + protected void runSelf() { times = new long[count]; for (int i = 0; i < count; ++i) { testable.run(); @@ -73,7 +70,6 @@ public class PerformanceTest extends SimpleTest { mode = current_value; } } - hasRun = true; result = callback.apply(testable); } diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index 5f335b9..498fce1 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -120,7 +120,7 @@ public class ECTesterStandalone { } catch (NoSuchAlgorithmException nsaex) { System.err.println("Algorithm not supported by the selected library: " + nsaex.getMessage()); nsaex.printStackTrace(); - } catch (InvalidKeyException | SignatureException | TestException e) { + } catch (InvalidKeyException | SignatureException e) { e.printStackTrace(); } } diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java index 5f697c4..7672c4b 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java @@ -3,7 +3,6 @@ package cz.crcs.ectester.standalone.test; import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.SimpleTest; import cz.crcs.ectester.common.test.TestCallback; -import cz.crcs.ectester.common.test.TestException; import java.util.Arrays; @@ -45,13 +44,4 @@ public class KeyAgreementTest extends SimpleTest { public String getDescription() { return "KeyAgreement " + testable.getKa().getAlgorithm(); } - - @Override - public void run() throws TestException { - if (hasRun) - return; - testable.run(); - result = callback.apply(testable); - hasRun = true; - } } diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java index de9356b..8a635e0 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java @@ -70,7 +70,7 @@ public class KeyAgreementTestable extends BaseTestable { } @Override - public void run() throws TestException { + public void run() { if (kgtPrivate != null) { privateKey = (ECPrivateKey) kgtPrivate.getKeyPair().getPrivate(); } diff --git a/src/cz/crcs/ectester/standalone/test/KeyGeneratorTest.java b/src/cz/crcs/ectester/standalone/test/KeyGeneratorTest.java index 93273ca..a27c088 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyGeneratorTest.java +++ b/src/cz/crcs/ectester/standalone/test/KeyGeneratorTest.java @@ -30,13 +30,4 @@ public class KeyGeneratorTest extends SimpleTest { public String getDescription() { return "KeyPairGenerator " + testable.getKpg().getAlgorithm(); } - - @Override - public void run() throws TestException { - if (hasRun) - return; - testable.run(); - result = callback.apply(testable); - hasRun = true; - } } diff --git a/src/cz/crcs/ectester/standalone/test/KeyGeneratorTestable.java b/src/cz/crcs/ectester/standalone/test/KeyGeneratorTestable.java index c2fec5a..353e87a 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyGeneratorTestable.java +++ b/src/cz/crcs/ectester/standalone/test/KeyGeneratorTestable.java @@ -40,7 +40,7 @@ public class KeyGeneratorTestable extends BaseTestable { } @Override - public void run() throws TestException { + public void run() { try { if (spec != null) { kpg.initialize(spec); diff --git a/src/cz/crcs/ectester/standalone/test/SignatureTest.java b/src/cz/crcs/ectester/standalone/test/SignatureTest.java index 9746b91..74c06f0 100644 --- a/src/cz/crcs/ectester/standalone/test/SignatureTest.java +++ b/src/cz/crcs/ectester/standalone/test/SignatureTest.java @@ -3,7 +3,6 @@ package cz.crcs.ectester.standalone.test; import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.SimpleTest; import cz.crcs.ectester.common.test.TestCallback; -import cz.crcs.ectester.common.test.TestException; /** * @author Jan Jancar johny@neuromancer.sk @@ -30,13 +29,4 @@ public class SignatureTest extends SimpleTest { public String getDescription() { return "Signature " + testable.getSig().getAlgorithm(); } - - @Override - public void run() throws TestException { - if (hasRun) - return; - testable.run(); - result = callback.apply(testable); - hasRun = true; - } } diff --git a/src/cz/crcs/ectester/standalone/test/SignatureTestable.java b/src/cz/crcs/ectester/standalone/test/SignatureTestable.java index 7b26af7..c77e9c5 100644 --- a/src/cz/crcs/ectester/standalone/test/SignatureTestable.java +++ b/src/cz/crcs/ectester/standalone/test/SignatureTestable.java @@ -56,7 +56,7 @@ public class SignatureTestable extends BaseTestable { } @Override - public void run() throws TestException { + public void run() { if (kgt != null) { signKey = (ECPrivateKey) kgt.getKeyPair().getPrivate(); verifyKey = (ECPublicKey) kgt.getKeyPair().getPublic(); -- cgit v1.2.3-70-g09d2 From ec84a28d3930140f908e18cd82562357abcf84a8 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 14 Mar 2018 21:23:45 +0100 Subject: Rename the CORRUPT command to TRANSFORM, as it does that now. --- src/cz/crcs/ectester/applet/ECKeyGenerator.java | 20 ++++---- src/cz/crcs/ectester/applet/ECKeyTester.java | 12 ++--- src/cz/crcs/ectester/applet/ECTesterApplet.java | 58 ++++++++++----------- src/cz/crcs/ectester/applet/EC_Consts.java | 54 +++++++++---------- src/cz/crcs/ectester/common/util/CardUtil.java | 24 ++++----- src/cz/crcs/ectester/reader/ECTesterReader.java | 2 +- src/cz/crcs/ectester/reader/command/Command.java | 60 +++++++++++----------- src/cz/crcs/ectester/reader/response/Response.java | 14 ++--- .../reader/test/CardCofactorTestSuite.java | 2 +- .../reader/test/CardCompositeCurvesSuite.java | 2 +- .../ectester/reader/test/CardDefaultSuite.java | 4 +- .../reader/test/CardInvalidCurvesSuite.java | 2 +- .../ectester/reader/test/CardTestVectorSuite.java | 3 +- .../ectester/reader/test/CardTwistTestSuite.java | 2 +- .../ectester/reader/test/CardWrongCurvesSuite.java | 10 ++-- 15 files changed, 134 insertions(+), 135 deletions(-) (limited to 'src/cz/crcs/ectester/reader/command/Command.java') diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java index 244bdba..9150248 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -139,38 +139,38 @@ public class ECKeyGenerator { /** * @param keypair - * @param corruptParams - * @param corruption + * @param params + * @param transformation * @param buffer * @param offset * @return */ - public short corruptCurve(KeyPair keypair, short corruptParams, short corruption, byte[] buffer, short offset) { - return corruptCurve(keypair, EC_Consts.KEY_BOTH, corruptParams, corruption, buffer, offset); + public short transformCurve(KeyPair keypair, short params, short transformation, byte[] buffer, short offset) { + return transformCurve(keypair, EC_Consts.KEY_BOTH, params, transformation, buffer, offset); } /** * @param keypair * @param key - * @param corruptParams - * @param corruption + * @param params + * @param transformation * @param buffer * @param offset * @return */ - public short corruptCurve(KeyPair keypair, byte key, short corruptParams, short corruption, byte[] buffer, short offset) { + public short transformCurve(KeyPair keypair, byte key, short params, short transformation, byte[] buffer, short offset) { sw = ISO7816.SW_NO_ERROR; - if (corruptParams == EC_Consts.PARAMETERS_NONE) { + if (params == EC_Consts.PARAMETERS_NONE) { return sw; } //go through param bit by bit, and invalidate all selected params short paramMask = EC_Consts.PARAMETER_FP; while (paramMask <= EC_Consts.PARAMETER_S) { - short masked = (short) (paramMask & corruptParams); + short masked = (short) (paramMask & params); if (masked != 0) { short length = exportParameter(keypair, key, masked, buffer, offset); - length = EC_Consts.corruptParameter(corruption, buffer, offset, length); + length = EC_Consts.transformParameter(transformation, buffer, offset, length); sw = setParameter(keypair, key, masked, buffer, offset, length); if (sw != ISO7816.SW_NO_ERROR) break; } diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 36515ef..27bb9e1 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -52,10 +52,10 @@ public class ECKeyTester { * @param pubkeyOffset offset into pubkeyBuffer that can be used for the public key * @param outputBuffer buffer to be used for the secret output * @param outputOffset offset into the outputBuffer - * @param corruption (EC_Consts.CORRUPTION_* | ...) + * @param transformation (EC_Consts.TRANSFORMATION_* | ...) * @return derived secret length **/ - public short testKA(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { + public short testKA(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short transformation) { short length = 0; try { sw = AppletUtil.kaCheck(ecKeyAgreement); @@ -64,7 +64,7 @@ public class ECKeyTester { short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); ecKeyAgreement.init(privatePair.getPrivate()); - pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength); + pubkeyLength = EC_Consts.transformParameter(transformation, pubkeyBuffer, pubkeyOffset, pubkeyLength); length = ecKeyAgreement.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); } catch (CardRuntimeException ce) { sw = ce.getReason(); @@ -79,17 +79,17 @@ public class ECKeyTester { * @param pubkeyLength * @param outpuBuffer * @param outputOffset - * @param corruption + * @param transformation * @return */ - public short testKA_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) { + public short testKA_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short transformation) { short length = 0; try { sw = AppletUtil.kaCheck(ecKeyAgreement); sw = AppletUtil.keypairCheck(privatePair); ecKeyAgreement.init(privatePair.getPrivate()); - pubkeyLength = EC_Consts.corruptParameter(corruption, pubkey, pubkeyOffset, pubkeyLength); + pubkeyLength = EC_Consts.transformParameter(transformation, pubkey, pubkeyOffset, pubkeyLength); length = ecKeyAgreement.generateSecret(pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset); } catch (CardRuntimeException ce) { sw = ce.getReason(); diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index e34e52c..18c4d1f 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -45,7 +45,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte INS_ALLOCATE = (byte) 0x5a; public static final byte INS_CLEAR = (byte) 0x5b; public static final byte INS_SET = (byte) 0x5c; - public static final byte INS_CORRUPT = (byte) 0x5d; + public static final byte INS_TRANSFORM = (byte) 0x5d; public static final byte INS_GENERATE = (byte) 0x5e; public static final byte INS_EXPORT = (byte) 0x5f; public static final byte INS_ECDH = (byte) 0x70; @@ -185,8 +185,8 @@ public class ECTesterApplet extends Applet implements ExtendedLength { case INS_SET: length = insSet(apdu); break; - case INS_CORRUPT: - length = insCorrupt(apdu); + case INS_TRANSFORM: + length = insTransform(apdu); break; case INS_GENERATE: length = insGenerate(apdu); @@ -344,29 +344,29 @@ public class ECTesterApplet extends Applet implements ExtendedLength { } /** - * Corrupts curve paramaters of local and remote keyPairs. - * returns corruptCurve SWs + * Transforms curve paramaters of local and remote keyPairs. + * returns transformCurve SWs * * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = byte key (EC_Consts.KEY_* | ...) * DATA = short params (EC_Consts.PARAMETER_* | ...) - * short corruption (EC_Consts.CORRUPTION_* || ...) + * short transformation (EC_Consts.TRANSFORMATION_* || ...) * @return length of response */ - private short insCorrupt(APDU apdu) { + private short insTransform(APDU apdu) { byte keyPair = apduArray[ISO7816.OFFSET_P1]; byte key = apduArray[ISO7816.OFFSET_P2]; short cdata = apdu.getOffsetCdata(); short params = Util.getShort(apduArray, cdata); - short corruption = Util.getShort(apduArray, (short) (cdata + 2)); + short transformation = Util.getShort(apduArray, (short) (cdata + 2)); short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += corrupt(localKeypair, key, params, corruption, apdu.getBuffer(), (short) 0); + len += transform(localKeypair, key, params, transformation, apdu.getBuffer(), (short) 0); } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += corrupt(remoteKeypair, key, params, corruption, apdu.getBuffer(), len); + len += transform(remoteKeypair, key, params, transformation, apdu.getBuffer(), len); } return len; @@ -429,7 +429,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * @param apdu P1 = byte pubkey (KEYPAIR_*) * P2 = byte privkey (KEYPAIR_*) * DATA = byte export (EXPORT_TRUE || EXPORT_FALSE) - * short corruption (EC_Consts.CORRUPTION_* | ...) + * short transformation (EC_Consts.TRANSFORMATION_* | ...) * byte type (EC_Consts.KA_* | ...) * @return length of response */ @@ -438,10 +438,10 @@ public class ECTesterApplet extends Applet implements ExtendedLength { byte privkey = apduArray[ISO7816.OFFSET_P2]; short cdata = apdu.getOffsetCdata(); byte export = apduArray[cdata]; - short corruption = Util.getShort(apduArray, (short) (cdata + 1)); + short transformation = Util.getShort(apduArray, (short) (cdata + 1)); byte type = apduArray[(short) (cdata + 3)]; - return ecdh(pubkey, privkey, export, corruption, type, apdu.getBuffer(), (short) 0); + return ecdh(pubkey, privkey, export, transformation, type, apdu.getBuffer(), (short) 0); } /** @@ -449,7 +449,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * * @param apdu P1 = byte privkey (KEYPAIR_*) * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE) - * DATA = short corruption (EC_Consts.CORRUPTION_* | ...) + * DATA = short transformation (EC_Consts.TRANSFORMATION_* | ...) * byte type (EC_Consts.KA_* | ...) * short length * byte[] pubkey @@ -459,11 +459,11 @@ public class ECTesterApplet extends Applet implements ExtendedLength { byte privkey = apduArray[ISO7816.OFFSET_P1]; byte export = apduArray[ISO7816.OFFSET_P2]; short cdata = apdu.getOffsetCdata(); - short corruption = Util.getShort(apduArray, cdata); + short transformation = Util.getShort(apduArray, cdata); byte type = apduArray[(short) (cdata + 2)]; short length = Util.getShort(apduArray, (short) (cdata + 3)); - return ecdh_direct(privkey, export, corruption, type, (short) (cdata + 5), length, apdu.getBuffer(), (short) 0); + return ecdh_direct(privkey, export, transformation, type, (short) (cdata + 5), length, apdu.getBuffer(), (short) 0); } /** @@ -576,16 +576,16 @@ public class ECTesterApplet extends Applet implements ExtendedLength { } /** - * @param keyPair KeyPair to corrupt - * @param key key to corrupt (EC_Consts.KEY_* | ...) - * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) - * @param corruption corruption type (EC_Consts.CORRUPTION_*) + * @param keyPair KeyPair to transform + * @param key key to transform (EC_Consts.KEY_* | ...) + * @param params parameters to transform (EC_Consts.PARAMETER_* | ...) + * @param transformation transformation type (EC_Consts.TRANSFORMATION_*) * @param outBuffer buffer to output sw to * @param outOffset output offset in buffer * @return length of data written to the buffer */ - private short corrupt(KeyPair keyPair, byte key, short params, short corruption, byte[] outBuffer, short outOffset) { - short sw = keyGenerator.corruptCurve(keyPair, key, params, corruption, ramArray, (short) 0); + private short transform(KeyPair keyPair, byte key, short params, short transformation, byte[] outBuffer, short outOffset) { + short sw = keyGenerator.transformCurve(keyPair, key, params, transformation, ramArray, (short) 0); Util.setShort(outBuffer, outOffset, sw); return 2; } @@ -635,13 +635,13 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret - * @param corruption whether to invalidate the pubkey before ECDH + * @param transformation whether to transform the pubkey before ECDH * @param type KeyAgreement type to test * @param outBuffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)} * @param outOffset output offset in buffer * @return length of data written to the buffer */ - private short ecdh(byte pubkey, byte privkey, byte export, short corruption, byte type, byte[] outBuffer, short outOffset) { + private short ecdh(byte pubkey, byte privkey, byte export, short transformation, byte type, byte[] outBuffer, short outOffset) { short length = 0; KeyPair pub = ((pubkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; @@ -649,11 +649,11 @@ public class ECTesterApplet extends Applet implements ExtendedLength { short secretLength = 0; if (keyTester.getKaType() == type) { - secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); + secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, transformation); } else { short allocateSW = keyTester.allocateKA(type); if (allocateSW == ISO7816.SW_NO_ERROR) { - secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); + secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, transformation); } } Util.setShort(outBuffer, outOffset, keyTester.getSW()); @@ -669,18 +669,18 @@ public class ECTesterApplet extends Applet implements ExtendedLength { return length; } - private short ecdh_direct(byte privkey, byte export, short corruption, byte type, short keyOffset, short keyLength, byte[] outBuffer, short outOffset) { + private short ecdh_direct(byte privkey, byte export, short transformation, byte type, short keyOffset, short keyLength, byte[] outBuffer, short outOffset) { short length = 0; KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; short secretLength = 0; if (keyTester.getKaType() == type) { - secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, corruption); + secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, transformation); } else { short allocateSW = keyTester.allocateKA(type); if (allocateSW == ISO7816.SW_NO_ERROR) { - secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, corruption); + secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, transformation); } } diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 008269a..5b3c74c 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -981,17 +981,17 @@ public class EC_Consts { public static final short EC571_F2M_K = 2; - // getCorruptCurveParameter PARAMETER_CORRUPTION TYPES - public static final short CORRUPTION_NONE = (short) 0x00; - public static final short CORRUPTION_FIXED = (short) 0x01; - public static final short CORRUPTION_FULLRANDOM = (short) 0x02; - public static final short CORRUPTION_ONEBYTERANDOM = (short) 0x04; - public static final short CORRUPTION_ZERO = (short) 0x08; - public static final short CORRUPTION_ONE = (short) 0x10; - public static final short CORRUPTION_MAX = (short) 0x20; - public static final short CORRUPTION_INCREMENT = (short) 0x40; - public static final short CORRUPTION_INFINITY = (short) 0x80; - public static final short CORRUPTION_COMPRESS = (short) 0x0100; + // transformParameter TRANSFORMATION types + public static final short TRANSFORMATION_NONE = (short) 0x00; + public static final short TRANSFORMATION_FIXED = (short) 0x01; + public static final short TRANSFORMATION_FULLRANDOM = (short) 0x02; + public static final short TRANSFORMATION_ONEBYTERANDOM = (short) 0x04; + public static final short TRANSFORMATION_ZERO = (short) 0x08; + public static final short TRANSFORMATION_ONE = (short) 0x10; + public static final short TRANSFORMATION_MAX = (short) 0x20; + public static final short TRANSFORMATION_INCREMENT = (short) 0x40; + public static final short TRANSFORMATION_INFINITY = (short) 0x80; + public static final short TRANSFORMATION_COMPRESS = (short) 0x0100; // toX962 FORM types public static final byte X962_UNCOMPRESSED = (byte) 0x00; @@ -1307,27 +1307,27 @@ public class EC_Consts { return length; } - public static short corruptParameter(short corruption, byte[] buffer, short offset, short length) { - if (corruption == CORRUPTION_NONE) { + public static short transformParameter(short transformation, byte[] buffer, short offset, short length) { + if (transformation == TRANSFORMATION_NONE) { return length; } - short corruptionMask = CORRUPTION_FIXED; - while (corruptionMask <= CORRUPTION_COMPRESS) { - short corruptionPart = (short) (corruptionMask & corruption); - switch (corruptionPart) { + short transformationMask = TRANSFORMATION_FIXED; + while (transformationMask <= TRANSFORMATION_COMPRESS) { + short transformationPart = (short) (transformationMask & transformation); + switch (transformationPart) { case (short) 0: break; - case CORRUPTION_FIXED: + case TRANSFORMATION_FIXED: if (length >= 1) { buffer[offset] = (byte) 0xcc; buffer[(short) (offset + length - 1)] = (byte) 0xcc; } break; - case CORRUPTION_FULLRANDOM: + case TRANSFORMATION_FULLRANDOM: randomData.generateData(buffer, offset, length); break; - case CORRUPTION_ONEBYTERANDOM: + case TRANSFORMATION_ONEBYTERANDOM: short first = Util.getShort(buffer, (short) 0); // save first two bytes randomData.generateData(buffer, (short) 0, (short) 2); // generate position @@ -1345,17 +1345,17 @@ public class EC_Consts { randomData.generateData(buffer, rngPos, (short) 1); } while (original == buffer[rngPos]); break; - case CORRUPTION_ZERO: + case TRANSFORMATION_ZERO: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); break; - case CORRUPTION_ONE: + case TRANSFORMATION_ONE: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); buffer[(short) (offset + length)] = (byte) 1; break; - case CORRUPTION_MAX: + case TRANSFORMATION_MAX: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 1); break; - case CORRUPTION_INCREMENT: + case TRANSFORMATION_INCREMENT: short index = (short) (offset + length - 1); byte value; do { @@ -1363,11 +1363,11 @@ public class EC_Consts { buffer[index--] = ++value; } while (value == (byte) 0 && index >= offset); break; - case CORRUPTION_INFINITY: + case TRANSFORMATION_INFINITY: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); length = 1; break; - case CORRUPTION_COMPRESS: + case TRANSFORMATION_COMPRESS: if ((short) (length % 2) != 1) { // an uncompressed point should have odd length (since 1 byte type, + 2 * coords) ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); @@ -1387,7 +1387,7 @@ public class EC_Consts { default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } - corruptionMask = (short) (corruptionMask << 1); + transformationMask = (short) (transformationMask << 1); } return length; } diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java index 1349879..3df5829 100644 --- a/src/cz/crcs/ectester/common/util/CardUtil.java +++ b/src/cz/crcs/ectester/common/util/CardUtil.java @@ -179,27 +179,27 @@ public class CardUtil { } } - public static String getCorruption(short corruptionType) { - switch (corruptionType) { - case EC_Consts.CORRUPTION_NONE: + public static String getTransformation(short transformationType) { + switch (transformationType) { + case EC_Consts.TRANSFORMATION_NONE: return "NONE"; - case EC_Consts.CORRUPTION_FIXED: + case EC_Consts.TRANSFORMATION_FIXED: return "FIXED"; - case EC_Consts.CORRUPTION_ONE: + case EC_Consts.TRANSFORMATION_ONE: return "ONE"; - case EC_Consts.CORRUPTION_ZERO: + case EC_Consts.TRANSFORMATION_ZERO: return "ZERO"; - case EC_Consts.CORRUPTION_ONEBYTERANDOM: + case EC_Consts.TRANSFORMATION_ONEBYTERANDOM: return "ONE_BYTE_RANDOM"; - case EC_Consts.CORRUPTION_FULLRANDOM: + case EC_Consts.TRANSFORMATION_FULLRANDOM: return "FULL_RANDOM"; - case EC_Consts.CORRUPTION_INCREMENT: + case EC_Consts.TRANSFORMATION_INCREMENT: return "INCREMENT"; - case EC_Consts.CORRUPTION_INFINITY: + case EC_Consts.TRANSFORMATION_INFINITY: return "INFINITY"; - case EC_Consts.CORRUPTION_COMPRESS: + case EC_Consts.TRANSFORMATION_COMPRESS: return "COMPRESSED"; - case EC_Consts.CORRUPTION_MAX: + case EC_Consts.TRANSFORMATION_MAX: return "MAX"; default: return "unknown"; diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 1e8b8a4..302df84 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -488,7 +488,7 @@ public class ECTesterReader { byte pubkey_bytes[] = export.getParameter(pubkey, EC_Consts.PARAMETER_W); byte privkey_bytes[] = export.getParameter(privkey, EC_Consts.PARAMETER_S); - Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECKAType).send(); + Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType).send(); ecdh.add(perform); for (Response r : ecdh) { respWriter.outputResponse(r); diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 5e025d8..25b41dd 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -405,44 +405,44 @@ public abstract class Command { /** * */ - public static class Corrupt extends Command { + public static class Transform extends Command { private byte keyPair; private byte key; private short params; - private short corruption; + private short transformation; /** * @param cardManager cardManager to send APDU through - * @param keyPair which keyPair to corrupt, local/remote (KEYPAIR_* || ...) - * @param key key to corrupt (EC_Consts.KEY_* | ...) - * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) - * @param corruption corruption type (EC_Consts.CORRUPTION_*) + * @param keyPair which keyPair to transform, local/remote (KEYPAIR_* || ...) + * @param key key to transform (EC_Consts.KEY_* | ...) + * @param params parameters to transform (EC_Consts.PARAMETER_* | ...) + * @param transformation transformation type (EC_Consts.TRANSFORMATION_*) */ - public Corrupt(CardMngr cardManager, byte keyPair, byte key, short params, short corruption) { + public Transform(CardMngr cardManager, byte keyPair, byte key, short params, short transformation) { super(cardManager); this.keyPair = keyPair; this.key = key; this.params = params; - this.corruption = corruption; + this.transformation = transformation; byte[] data = new byte[4]; ByteUtil.setShort(data, 0, params); - ByteUtil.setShort(data, 2, corruption); + ByteUtil.setShort(data, 2, transformation); - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CORRUPT, keyPair, key, data); + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_TRANSFORM, keyPair, key, data); } @Override - public Response.Corrupt send() throws CardException { + public Response.Transform send() throws CardException { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Corrupt(response, getDescription(), elapsed, keyPair, key, params, corruption); + return new Response.Transform(response, getDescription(), elapsed, keyPair, key, params, transformation); } @Override public String getDescription() { - String corrupt = CardUtil.getCorruption(corruption); + String transform = CardUtil.getTransformation(transformation); String pair; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { @@ -450,7 +450,7 @@ public abstract class Command { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Corrupt params of %s, %s", pair, corrupt); + return String.format("Transform params of %s, %s", pair, transform); } } @@ -556,7 +556,7 @@ public abstract class Command { private byte pubkey; private byte privkey; private byte export; - private short corruption; + private short transformation; private byte type; /** @@ -566,19 +566,19 @@ public abstract class Command { * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret - * @param corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) + * @param transformation whether to transform the pubkey before ECDH (EC_Consts.TRANSFORMATION_* | ...) * @param type ECDH algorithm type (EC_Consts.KA_* | ...) */ - public ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, short corruption, byte type) { + public ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, short transformation, byte type) { super(cardManager); this.pubkey = pubkey; this.privkey = privkey; this.export = export; - this.corruption = corruption; + this.transformation = transformation; this.type = type; byte[] data = new byte[]{export, 0, 0, type}; - ByteUtil.setShort(data, 1, corruption); + ByteUtil.setShort(data, 1, transformation); this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); } @@ -588,7 +588,7 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDH(response, getDescription(), elapsed, pubkey, privkey, export, corruption, type); + return new Response.ECDH(response, getDescription(), elapsed, pubkey, privkey, export, transformation, type); } @Override @@ -599,10 +599,10 @@ public abstract class Command { String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String validity; - if (corruption == EC_Consts.CORRUPTION_NONE) { + if (transformation == EC_Consts.TRANSFORMATION_NONE) { validity = "unchanged"; } else { - validity = CardUtil.getCorruption(corruption); + validity = CardUtil.getTransformation(transformation); } return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity); } @@ -614,7 +614,7 @@ public abstract class Command { public static class ECDH_direct extends Command { private byte privkey; private byte export; - private short corruption; + private short transformation; private byte type; private byte[] pubkey; @@ -624,20 +624,20 @@ public abstract class Command { * @param cardManager cardManager to send APDU through * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret - * @param corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) + * @param transformation whether to transform the pubkey before ECDH (EC_Consts.TRANSFORMATION_* | ...) * @param type EC KeyAgreement type * @param pubkey pubkey data to do ECDH with. */ - public ECDH_direct(CardMngr cardManager, byte privkey, byte export, short corruption, byte type, byte[] pubkey) { + public ECDH_direct(CardMngr cardManager, byte privkey, byte export, short transformation, byte type, byte[] pubkey) { super(cardManager); this.privkey = privkey; this.export = export; - this.corruption = corruption; + this.transformation = transformation; this.type = type; this.pubkey = pubkey; byte[] data = new byte[3 + pubkey.length]; - ByteUtil.setShort(data, 0, corruption); + ByteUtil.setShort(data, 0, transformation); data[2] = type; System.arraycopy(pubkey, 0, data, 3, pubkey.length); @@ -649,7 +649,7 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDH(response, getDescription(), elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, corruption, type); + return new Response.ECDH(response, getDescription(), elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, transformation, type); } @Override @@ -659,10 +659,10 @@ public abstract class Command { String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String validity; - if (corruption == EC_Consts.CORRUPTION_NONE) { + if (transformation == EC_Consts.TRANSFORMATION_NONE) { validity = "unchanged"; } else { - validity = CardUtil.getCorruption(corruption); + validity = CardUtil.getTransformation(transformation); } return String.format("%s of external pubkey and %s privkey(%s point)", algo, priv, validity); } diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 5a9a458..4814e41 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -222,18 +222,18 @@ public abstract class Response { /** * */ - public static class Corrupt extends Response { + public static class Transform extends Response { private byte keyPair; private byte key; private short params; - private short corruption; + private short transformation; - public Corrupt(ResponseAPDU response, String description, long time, byte keyPair, byte key, short params, short corruption) { + public Transform(ResponseAPDU response, String description, long time, byte keyPair, byte key, short params, short transformation) { super(response, description, time); this.keyPair = keyPair; this.key = key; this.params = params; - this.corruption = corruption; + this.transformation = transformation; int pairs = 0; if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; @@ -358,15 +358,15 @@ public abstract class Response { private byte pubkey; private byte privkey; private byte export; - private short corruption; + private short transformation; private byte type; - public ECDH(ResponseAPDU response, String description, long time, byte pubkey, byte privkey, byte export, short corruption, byte type) { + public ECDH(ResponseAPDU response, String description, long time, byte pubkey, byte privkey, byte export, short transformation, byte type) { super(response, description, time); this.pubkey = pubkey; this.privkey = privkey; this.export = export; - this.corruption = corruption; + this.transformation = transformation; this.type = type; parse(1, (export == ECTesterApplet.EXPORT_TRUE) ? 1 : 0); diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java index fd3f0ae..a0b71a7 100644 --- a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java @@ -48,7 +48,7 @@ public class CardCofactorTestSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on non-generator subgroup", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index b931aad..f0eaa87 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -39,7 +39,7 @@ public class CardCompositeCurvesSuite extends CardTestSuite { Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); Test ecdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key."); doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java index cb5e0c9..dd9c8c8 100644 --- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -59,9 +59,9 @@ public class CardDefaultSuite extends CardTestSuite { for (byte kaType : EC_Consts.KA_TYPES) { Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS)); if (allocate.ok()) { - Command ecdh = new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, kaType); + Command ecdh = new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType); Test ka = runTest(CommandTest.expect(ecdh, ExpectedValue.SUCCESS)); - Test kaCompressed = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, kaType), ExpectedValue.SUCCESS)); + Test kaCompressed = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), ExpectedValue.SUCCESS)); Test perfTest = null; if (ka.ok()) { perfTest = runTest(PerformanceTest.repeat(ecdh, 10)); diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index 0cf27ec..fab7786 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -53,7 +53,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.")); } Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java index de267c3..9d39525 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -11,7 +11,6 @@ import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; -import javacard.security.KeyPair; import java.io.IOException; import java.util.LinkedList; @@ -55,7 +54,7 @@ public class CardTestVectorSuite extends CardTestSuite { testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback() { + testVector.add(CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, result.getJavaCardKA()), new TestCallback() { @Override public Result apply(CommandTestable testable) { Response.ECDH dh = (Response.ECDH) testable.getResponse(); diff --git a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java index fad508f..4b90694 100644 --- a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java @@ -48,7 +48,7 @@ public class CardTwistTestSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 4706bdd..5d58be1 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -55,7 +55,7 @@ public class CardWrongCurvesSuite extends CardTestSuite { for (byte kaType : EC_Consts.KA_TYPES) { Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS)); if (allocate.ok()) { - Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, kaType), Result.ExpectedValue.FAILURE)); + Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), Result.ExpectedValue.FAILURE)); Test kaTest = runTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "Allocate and perform KA, should fail.", allocate, ka)); tests.add(kaTest); } @@ -81,8 +81,8 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_FP, null), Result.ExpectedValue.SUCCESS)); Test setup = runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set)); - Test prime0 = ecdhTest(new Command.Corrupt(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.CORRUPTION_ZERO), "Set p = 0.", "ECDH with p = 0."); - Test prime1 = ecdhTest(new Command.Corrupt(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.CORRUPTION_ONE), "Set p = 1.", "ECDH with p = 1."); + Test prime0 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.TRANSFORMATION_ZERO), "Set p = 0.", "ECDH with p = 0."); + Test prime1 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.TRANSFORMATION_ONE), "Set p = 1.", "ECDH with p = 1."); short keyHalf = (short) (keyLength / 2); BigInteger prime = new BigInteger(keyHalf, r); @@ -116,7 +116,7 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_F2M, null), Result.ExpectedValue.SUCCESS)); Test setup = runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set)); - Test coeff0 = ecdhTest(new Command.Corrupt(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_F2M, EC_Consts.CORRUPTION_ZERO), "Set e1 = e2 = e3 = 0.", "ECDH with wrong field polynomial: x^" + keyLength); + Test coeff0 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_F2M, EC_Consts.TRANSFORMATION_ZERO), "Set e1 = e2 = e3 = 0.", "ECDH with wrong field polynomial: x^" + keyLength); short e1 = (short) (2 * keyLength); short e2 = (short) (3 * keyLength); @@ -147,7 +147,7 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.FAILURE)); Test preparePhase = runTest(CompoundTest.any(Result.ExpectedValue.SUCCESS, prepareDesc, setup, generate)); Test allocateECDH = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.SUCCESS)); - Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); + Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); return runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, fullDesc, preparePhase, allocateECDH, ecdh)); } } -- cgit v1.2.3-70-g09d2 From efc1a237f83a6fe7bcfaced2aaebcfeae116a774 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 5 Apr 2018 00:38:24 +0200 Subject: Add ECDSA_sign and ECDSA_verify commands, to allow separate testing. --- src/cz/crcs/ectester/applet/ECKeyTester.java | 50 +++++++ src/cz/crcs/ectester/applet/ECTesterApplet.java | 148 +++++++++++++++++---- src/cz/crcs/ectester/applet/EC_Consts.java | 45 +++++-- src/cz/crcs/ectester/common/util/CardUtil.java | 52 ++++---- src/cz/crcs/ectester/reader/ECTesterReader.java | 4 +- src/cz/crcs/ectester/reader/command/Command.java | 113 ++++++++++++++++ .../reader/test/CardCofactorTestSuite.java | 2 +- .../reader/test/CardCompositeCurvesSuite.java | 2 +- .../reader/test/CardInvalidCurvesSuite.java | 2 +- .../ectester/reader/test/CardTwistTestSuite.java | 2 +- .../ectester/reader/test/CardWrongCurvesSuite.java | 4 +- 11 files changed, 347 insertions(+), 77 deletions(-) (limited to 'src/cz/crcs/ectester/reader/command/Command.java') diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 27bb9e1..7c091e3 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -130,6 +130,56 @@ public class ECKeyTester { return length; } + /** + * + * @param signKey + * @param inputBuffer + * @param inputOffset + * @param inputLength + * @param sigBuffer + * @param sigOffset + * @return + */ + public short testECDSA_sign(ECPrivateKey signKey, byte[] inputBuffer, short inputOffset, short inputLength, byte[] sigBuffer, short sigOffset) { + short length = 0; + try { + sw = AppletUtil.signCheck(ecdsaSignature); + + ecdsaSignature.init(signKey, Signature.MODE_SIGN); + length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); + } catch (CardRuntimeException ce) { + sw = ce.getReason(); + } + return length; + } + + /** + * + * @param verifyKey + * @param inputBuffer + * @param inputOffset + * @param inputLength + * @param sigBuffer + * @param sigOffset + * @param sigLength + * @return + */ + public short testECDSA_verify(ECPublicKey verifyKey, byte[] inputBuffer, short inputOffset, short inputLength, byte[] sigBuffer, short sigOffset, short sigLength) { + short length = 0; + try { + sw = AppletUtil.signCheck(ecdsaSignature); + + ecdsaSignature.init(verifyKey, Signature.MODE_VERIFY); + boolean correct = ecdsaSignature.verify(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset, sigLength); + if (!correct) { + sw = ECTesterApplet.SW_SIG_VERIFY_FAIL; + } + } catch (CardRuntimeException ce) { + sw = ce.getReason(); + } + return length; + } + public KeyAgreement getKA() { return ecKeyAgreement; } diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 18c4d1f..d0ca8f5 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -51,10 +51,11 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte INS_ECDH = (byte) 0x70; public static final byte INS_ECDH_DIRECT = (byte) 0x71; public static final byte INS_ECDSA = (byte) 0x72; - public static final byte INS_CLEANUP = (byte) 0x73; - //public static final byte INS_SUPPORT = (byte) 0x74; - public static final byte INS_ALLOCATE_KA = (byte) 0x75; - public static final byte INS_ALLOCATE_SIG = (byte) 0x76; + public static final byte INS_ECDSA_SIGN = (byte) 0x73; + public static final byte INS_ECDSA_VERIFY = (byte) 0x74; + public static final byte INS_CLEANUP = (byte) 0x75; + public static final byte INS_ALLOCATE_KA = (byte) 0x76; + public static final byte INS_ALLOCATE_SIG = (byte) 0x77; // PARAMETERS for P1 and P2 @@ -83,34 +84,12 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final short SW_TransactionException_prefix = (short) 0xf400; public static final short SW_CardRuntimeException_prefix = (short) 0xf500; - - // Class javacard.security.KeyAgreement - // javacard.security.KeyAgreement Fields: - public static final byte KeyAgreement_ALG_EC_SVDP_DH = 1; - public static final byte KeyAgreement_ALG_EC_SVDP_DH_KDF = 1; - public static final byte KeyAgreement_ALG_EC_SVDP_DHC = 2; - public static final byte KeyAgreement_ALG_EC_SVDP_DHC_KDF = 2; - public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN = 3; - public static final byte KeyAgreement_ALG_EC_SVDP_DHC_PLAIN = 4; - public static final byte KeyAgreement_ALG_EC_PACE_GM = 5; - public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6; - - // Class javacard.security.Signature - // javacard.security.Signature Fields: - public static final byte Signature_ALG_ECDSA_SHA = 17; - public static final byte Signature_ALG_ECDSA_SHA_256 = 33; - public static final byte Signature_ALG_ECDSA_SHA_384 = 34; - public static final byte Signature_ALG_ECDSA_SHA_224 = 37; - public static final byte Signature_ALG_ECDSA_SHA_512 = 38; - private static final short ARRAY_LENGTH = (short) 0xff; private static final short APDU_MAX_LENGTH = (short) 1024; // TEMPORARRY ARRAY IN RAM private byte[] ramArray = null; private byte[] ramArray2 = null; private byte[] apduArray = null; - // PERSISTENT ARRAY IN EEPROM - private byte[] dataArray = null; // unused private RandomData randomData = null; @@ -135,9 +114,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength { ramArray2 = JCSystem.makeTransientByteArray(ARRAY_LENGTH, JCSystem.CLEAR_ON_RESET); apduArray = JCSystem.makeTransientByteArray(APDU_MAX_LENGTH, JCSystem.CLEAR_ON_RESET); - dataArray = new byte[ARRAY_LENGTH]; - Util.arrayFillNonAtomic(dataArray, (short) 0, ARRAY_LENGTH, (byte) 0); - randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM); EC_Consts.randomData = randomData; @@ -203,6 +179,12 @@ public class ECTesterApplet extends Applet implements ExtendedLength { case INS_ECDSA: length = insECDSA(apdu); break; + case INS_ECDSA_SIGN: + length = insECDSA_sign(apdu); + break; + case INS_ECDSA_VERIFY: + length = insECDSA_verify(apdu); + break; case INS_CLEANUP: length = insCleanup(apdu); break; @@ -494,6 +476,57 @@ public class ECTesterApplet extends Applet implements ExtendedLength { return len; } + /** + * + * @param apdu P1 = byte keyPair (KEYPAIR_*) + * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE) + * DATA = byte sigType + * short dataLength (00 = random data generated, !00 = data length) + * byte[] data + * @return length of response + */ + private short insECDSA_sign(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte export = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + byte sigType = apduArray[cdata]; + + short len = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) { + len += ecdsa_sign(localKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), (short) 0); + } + if ((keyPair & KEYPAIR_REMOTE) != 0) { + len += ecdsa_sign(remoteKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), len); + } + return len; + } + + /** + * + * @param apdu P1 = byte keyPair (KEYPAIR_*) + * P2 = byte sigType + * DATA = short dataLength (00 = random data generated, !00 = data length) + * byte[] data + * short sigLength + * byte[] signature + * @return length of response + */ + private short insECDSA_verify(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte sigType = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + + short len = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) { + len += ecdsa_verify(localKeypair, sigType, apduArray, cdata, apdu.getBuffer(), (short) 0); + } + if ((keyPair & KEYPAIR_REMOTE) != 0) { + len += ecdsa_verify(remoteKeypair, sigType, apduArray, cdata, apdu.getBuffer(), len); + } + return len; + } + + /** * Performs card memory cleanup via JCSystem.requestObjectDeletion() * @@ -741,6 +774,63 @@ public class ECTesterApplet extends Applet implements ExtendedLength { return length; } + private short ecdsa_sign(KeyPair sign, byte sigType, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { + short length = 0; + + short dataLength = Util.getShort(inBuffer, inOffset); + if (dataLength == 0) { //no data to sign + //generate random + dataLength = 64; + randomData.generateData(ramArray, (short) 0, dataLength); + } else { + Util.arrayCopyNonAtomic(inBuffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength); + } + + short signatureLength = 0; + if (keyTester.getSigType() == sigType) { + signatureLength = keyTester.testECDSA_sign((ECPrivateKey) sign.getPrivate(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + } else { + short allocateSW = keyTester.allocateSig(sigType); + if (allocateSW == ISO7816.SW_NO_ERROR) { + signatureLength = keyTester.testECDSA_sign((ECPrivateKey) sign.getPrivate(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + } + } + Util.setShort(outBuffer, outOffset, keyTester.getSW()); + length += 2; + + if (export == EXPORT_TRUE) { + Util.setShort(outBuffer, (short) (outOffset + length), signatureLength); + length += 2; + + Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), signatureLength); + length += signatureLength; + } + + return length; + } + + private short ecdsa_verify(KeyPair verify, byte sigType, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { + short length = 0; + + short dataLength = Util.getShort(inBuffer, inOffset); + short dataOffset = (short)(inOffset + 2); + short sigLength = Util.getShort(inBuffer, (short)(dataOffset + dataLength)); + short sigOffset = (short)(dataOffset + dataLength + 2); + + if (keyTester.getSigType() == sigType) { + keyTester.testECDSA_verify((ECPublicKey) verify.getPublic(), inBuffer, dataOffset, dataLength, inBuffer, sigOffset, sigLength); + } else { + short allocateSW = keyTester.allocateSig(sigType); + if (allocateSW == ISO7816.SW_NO_ERROR) { + keyTester.testECDSA_verify((ECPublicKey) verify.getPublic(), inBuffer, dataOffset, dataLength, inBuffer, sigOffset, sigLength); + } + } + Util.setShort(outBuffer, outOffset, keyTester.getSW()); + length += 2; + + return length; + } + /** * @param buffer buffer to write sw to * @param offset output offset in buffer diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 5b3c74c..88a8bd6 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -12,6 +12,8 @@ import javacard.security.RandomData; */ public class EC_Consts { + public static final byte KeyAgreement_ALG_EC_SVDP_DH_KDF = 1; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC_KDF = 2; private static byte[] EC_FP_P = null; //p private static byte[] EC_A = null; //a private static byte[] EC_B = null; //b @@ -1026,23 +1028,40 @@ public class EC_Consts { public static final short[] FP_SIZES = new short[]{112, 128, 160, 192, 224, 256, 384, 521}; public static final short[] F2M_SIZES = new short[]{163, 233, 283, 409, 571}; + // Class javacard.security.KeyAgreement + // javacard.security.KeyAgreement Fields: + public static final byte KeyAgreement_ALG_EC_SVDP_DH = 1; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC = 2; + public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN = 3; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC_PLAIN = 4; + public static final byte KeyAgreement_ALG_EC_PACE_GM = 5; + public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6; + public static final byte[] KA_TYPES = new byte[]{ - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, - //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_KDF, //duplicate - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC, - //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_KDF, //duplicate - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN, - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN, - ECTesterApplet.KeyAgreement_ALG_EC_PACE_GM, - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY + KeyAgreement_ALG_EC_SVDP_DH, + //KeyAgreement_ALG_EC_SVDP_DH_KDF, //duplicate + KeyAgreement_ALG_EC_SVDP_DHC, + //KeyAgreement_ALG_EC_SVDP_DHC_KDF, //duplicate + KeyAgreement_ALG_EC_SVDP_DH_PLAIN, + KeyAgreement_ALG_EC_SVDP_DHC_PLAIN, + KeyAgreement_ALG_EC_PACE_GM, + KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY }; + // Class javacard.security.Signature + // javacard.security.Signature Fields: + public static final byte Signature_ALG_ECDSA_SHA = 17; + public static final byte Signature_ALG_ECDSA_SHA_224 = 37; + public static final byte Signature_ALG_ECDSA_SHA_256 = 33; + public static final byte Signature_ALG_ECDSA_SHA_384 = 34; + public static final byte Signature_ALG_ECDSA_SHA_512 = 38; + public static final byte[] SIG_TYPES = new byte[]{ - ECTesterApplet.Signature_ALG_ECDSA_SHA, - ECTesterApplet.Signature_ALG_ECDSA_SHA_224, - ECTesterApplet.Signature_ALG_ECDSA_SHA_256, - ECTesterApplet.Signature_ALG_ECDSA_SHA_384, - ECTesterApplet.Signature_ALG_ECDSA_SHA_512 + Signature_ALG_ECDSA_SHA, + Signature_ALG_ECDSA_SHA_224, + Signature_ALG_ECDSA_SHA_256, + Signature_ALG_ECDSA_SHA_384, + Signature_ALG_ECDSA_SHA_512 }; public static byte getCurve(short keyLength, byte keyClass) { diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java index 3df5829..2501e47 100644 --- a/src/cz/crcs/ectester/common/util/CardUtil.java +++ b/src/cz/crcs/ectester/common/util/CardUtil.java @@ -6,8 +6,6 @@ import javacard.framework.ISO7816; import javacard.security.CryptoException; import javacard.security.KeyPair; -import static cz.crcs.ectester.applet.ECTesterApplet.*; - /** * @author Petr Svenda petr@svenda.com * @author Jan Jancar johny@neuromancer.sk @@ -17,12 +15,12 @@ public class CardUtil { switch (name) { case "DH": case "ECDH": - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; case "DHC": case "ECDHC": - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC; default: - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; } } @@ -208,17 +206,17 @@ public class CardUtil { public static String getKATypeString(byte kaType) { switch (kaType) { - case KeyAgreement_ALG_EC_SVDP_DH: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH: return "ALG_EC_SVDP_DH"; - case KeyAgreement_ALG_EC_SVDP_DH_PLAIN: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN: return "ALG_EC_SVDP_DH_PLAIN"; - case KeyAgreement_ALG_EC_PACE_GM: + case EC_Consts.KeyAgreement_ALG_EC_PACE_GM: return "ALG_EC_PACE_GM"; - case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: return "ALG_EC_SVDP_DH_PLAIN_XY"; - case KeyAgreement_ALG_EC_SVDP_DHC: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC: return "ALG_EC_SVDP_DHC"; - case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: return "ALG_EC_SVDP_DHC_PLAIN"; default: return "unknown"; @@ -228,17 +226,17 @@ public class CardUtil { public static byte getKAType(String kaTypeString) { switch (kaTypeString) { case "ALG_EC_SVDP_DH": - return KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; case "ALG_EC_SVDP_DH_PLAIN": - return KeyAgreement_ALG_EC_SVDP_DH_PLAIN; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN; case "ALG_EC_PACE_GM": - return KeyAgreement_ALG_EC_PACE_GM; + return EC_Consts.KeyAgreement_ALG_EC_PACE_GM; case "ALG_EC_SVDP_DH_PLAIN_XY": - return KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY; case "ALG_EC_SVDP_DHC": - return KeyAgreement_ALG_EC_SVDP_DHC; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC; case "ALG_EC_SVDP_DHC_PLAIN": - return KeyAgreement_ALG_EC_SVDP_DHC_PLAIN; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN; default: return 0; } @@ -256,15 +254,15 @@ public class CardUtil { public static String getSigTypeString(byte sigType) { switch (sigType) { - case Signature_ALG_ECDSA_SHA: + case EC_Consts.Signature_ALG_ECDSA_SHA: return "ALG_ECDSA_SHA"; - case Signature_ALG_ECDSA_SHA_224: + case EC_Consts.Signature_ALG_ECDSA_SHA_224: return "ALG_ECDSA_SHA_224"; - case Signature_ALG_ECDSA_SHA_256: + case EC_Consts.Signature_ALG_ECDSA_SHA_256: return "ALG_ECDSA_SHA_256"; - case Signature_ALG_ECDSA_SHA_384: + case EC_Consts.Signature_ALG_ECDSA_SHA_384: return "ALG_ECDSA_SHA_384"; - case Signature_ALG_ECDSA_SHA_512: + case EC_Consts.Signature_ALG_ECDSA_SHA_512: return "ALG_ECDSA_SHA_512"; default: return "unknown"; @@ -274,15 +272,15 @@ public class CardUtil { public static byte getSigType(String sigTypeString) { switch (sigTypeString) { case "ALG_ECDSA_SHA": - return Signature_ALG_ECDSA_SHA; + return EC_Consts.Signature_ALG_ECDSA_SHA; case "ALG_ECDSA_SHA_224": - return Signature_ALG_ECDSA_SHA_224; + return EC_Consts.Signature_ALG_ECDSA_SHA_224; case "ALG_ECDSA_SHA_256": - return Signature_ALG_ECDSA_SHA_256; + return EC_Consts.Signature_ALG_ECDSA_SHA_256; case "ALG_ECDSA_SHA_384": - return Signature_ALG_ECDSA_SHA_384; + return EC_Consts.Signature_ALG_ECDSA_SHA_384; case "ALG_ECDSA_SHA_512": - return Signature_ALG_ECDSA_SHA_512; + return EC_Consts.Signature_ALG_ECDSA_SHA_512; default: return 0; } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index dfd71db..84c0439 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -49,8 +49,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Scanner; -import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; -import static cz.crcs.ectester.applet.ECTesterApplet.Signature_ALG_ECDSA_SHA; +import static cz.crcs.ectester.applet.EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; +import static cz.crcs.ectester.applet.EC_Consts.Signature_ALG_ECDSA_SHA; /** * Reader part of ECTester, a tool for testing Elliptic curve support on javacards. diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 25b41dd..d0eaf45 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -685,6 +685,10 @@ public abstract class Command { */ public ECDSA(CardMngr cardManager, byte keyPair, byte sigType, byte export, byte[] raw) { super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + this.keyPair = keyPair; this.sigType = sigType; this.export = export; @@ -718,6 +722,115 @@ public abstract class Command { } } + public static class ECDSA_sign extends Command { + private byte keyPair; + private byte sigType; + private byte export; + private byte[] raw; + + /** + * Creates the INS_ECDSA_SIGN instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param sigType Signature type to use + * @param export whether to export ECDSA signature + * @param raw data to sign, can be null, in which case random data is signed. + */ + public ECDSA_sign(CardMngr cardManager, byte keyPair, byte sigType, byte export, byte[] raw) { + super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + + this.keyPair = keyPair; + this.sigType = sigType; + this.export = export; + this.raw = raw; + + int len = raw != null ? raw.length : 0; + byte[] data = new byte[3 + len]; + data[0] = sigType; + ByteUtil.setShort(data, 1, (short) len); + if (raw != null) { + System.arraycopy(raw, 0, data, 3, len); + } + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA_SIGN, keyPair, export, data); + } + + @Override + public Response.ECDSA send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDSA(response, getDescription(), elapsed, keyPair, sigType, export, raw); + } + + @Override + public String getDescription() { + String algo = CardUtil.getSigTypeString(sigType); + String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String data = raw == null ? "random" : "provided"; + return String.format("%s signature with %s keypair(%s data)", algo, key, data); + } + } + + public static class ECDSA_verify extends Command { + private byte keyPair; + private byte sigType; + private byte[] raw; + private byte[] signature; + + /** + * Creates the INS_ECDSA_VERIFY instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param sigType Signature type to use + * @param raw data to sign + * @param signature signature data + */ + public ECDSA_verify(CardMngr cardManager, byte keyPair, byte sigType, byte[] raw, byte[] signature) { + super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + if (raw == null || signature == null) { + throw new IllegalArgumentException(); + } + + this.keyPair = keyPair; + this.sigType = sigType; + this.raw = raw; + this.signature = signature; + + byte[] data = new byte[4 + raw.length + signature.length]; + ByteUtil.setShort(data, 0, (short) raw.length); + System.arraycopy(raw, 0, data, 2, raw.length); + ByteUtil.setShort(data, 2 + raw.length, (short) signature.length); + System.arraycopy(signature, 0, data, 2 + raw.length + 2, signature.length); + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA_SIGN, keyPair, sigType, data); + } + + @Override + public Response.ECDSA send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDSA(response, getDescription(), elapsed, keyPair, sigType, ECTesterApplet.EXPORT_FALSE, raw); + } + + @Override + public String getDescription() { + String algo = CardUtil.getSigTypeString(sigType); + String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String data = raw == null ? "random" : "provided"; + return String.format("%s verification with %s keypair(%s data)", algo, key, data); + } + } + /** * */ diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java index a0b71a7..1ca05d4 100644 --- a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java @@ -48,7 +48,7 @@ public class CardCofactorTestSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on non-generator subgroup", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index f0eaa87..95204dd 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -39,7 +39,7 @@ public class CardCompositeCurvesSuite extends CardTestSuite { Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); Test ecdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key."); doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index fab7786..d3c5f99 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -53,7 +53,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.")); } Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java index 4b90694..c80db0d 100644 --- a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java @@ -48,7 +48,7 @@ public class CardTwistTestSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 5d58be1..429b047 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -146,8 +146,8 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test setup = runTest(CommandTest.expect(setupCmd, Result.ExpectedValue.FAILURE)); Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.FAILURE)); Test preparePhase = runTest(CompoundTest.any(Result.ExpectedValue.SUCCESS, prepareDesc, setup, generate)); - Test allocateECDH = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.SUCCESS)); - Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); + Test allocateECDH = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.SUCCESS)); + Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); return runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, fullDesc, preparePhase, allocateECDH, ecdh)); } } -- cgit v1.2.3-70-g09d2 From 16bd00ad0a82ae68068c3c3d60bd8ac5a723247b Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 17 Apr 2018 14:24:38 +0200 Subject: Fix ECDSA verify command. --- src/cz/crcs/ectester/reader/command/Command.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cz/crcs/ectester/reader/command/Command.java') diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index d0eaf45..8af2218 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -811,7 +811,7 @@ public abstract class Command { ByteUtil.setShort(data, 2 + raw.length, (short) signature.length); System.arraycopy(signature, 0, data, 2 + raw.length + 2, signature.length); - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA_SIGN, keyPair, sigType, data); + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA_VERIFY, keyPair, sigType, data); } @Override -- cgit v1.2.3-70-g09d2 From 662cc82a470a833a11e19a2dc8c1ce0e79c35935 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 27 Jun 2018 22:00:59 +0200 Subject: Implement more tests for wrong parameters. Implement cloning for Tests. - Test G = infinity. - Test wrong r, where [r]G != infinity, - prime - composite --- src/cz/crcs/ectester/applet/EC_Consts.java | 6 +- src/cz/crcs/ectester/common/test/BaseTestable.java | 7 +- src/cz/crcs/ectester/common/test/CompoundTest.java | 7 +- src/cz/crcs/ectester/common/test/SimpleTest.java | 15 ++- src/cz/crcs/ectester/common/test/Test.java | 7 +- src/cz/crcs/ectester/common/util/CardUtil.java | 129 +++++++++++++++++---- src/cz/crcs/ectester/reader/command/Command.java | 10 +- .../ectester/reader/test/CardWrongCurvesSuite.java | 27 ++++- .../ectester/standalone/ECTesterStandalone.java | 1 - 9 files changed, 174 insertions(+), 35 deletions(-) (limited to 'src/cz/crcs/ectester/reader/command/Command.java') diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index c24283a..3f3ddb6 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -995,6 +995,7 @@ public class EC_Consts { public static final short TRANSFORMATION_INFINITY = (short) 0x80; public static final short TRANSFORMATION_COMPRESS = (short) 0x0100; public static final short TRANSFORMATION_COMPRESS_HYBRID = (short) 0x0200; + public static final short TRANSFORMATION_04_MASK = (short) 0x0400; // toX962 FORM types public static final byte X962_UNCOMPRESSED = (byte) 0x00; @@ -1333,7 +1334,7 @@ public class EC_Consts { } short transformationMask = TRANSFORMATION_FIXED; - while (transformationMask <= TRANSFORMATION_COMPRESS) { + while (transformationMask <= TRANSFORMATION_04_MASK) { short transformationPart = (short) (transformationMask & transformation); switch (transformationPart) { case (short) 0: @@ -1408,6 +1409,9 @@ public class EC_Consts { buffer[offset] += 4; } break; + case TRANSFORMATION_04_MASK: + buffer[offset] = 4; + break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } diff --git a/src/cz/crcs/ectester/common/test/BaseTestable.java b/src/cz/crcs/ectester/common/test/BaseTestable.java index 4863abc..3c304d9 100644 --- a/src/cz/crcs/ectester/common/test/BaseTestable.java +++ b/src/cz/crcs/ectester/common/test/BaseTestable.java @@ -3,7 +3,7 @@ package cz.crcs.ectester.common.test; /** * @author Jan Jancar johny@neuromancer.sk */ -public abstract class BaseTestable implements Testable { +public abstract class BaseTestable implements Testable, Cloneable { protected boolean hasRun; protected boolean ok; protected boolean error; @@ -36,4 +36,9 @@ public abstract class BaseTestable implements Testable { error = false; errorCause = null; } + + @Override + protected BaseTestable clone() throws CloneNotSupportedException { + return (BaseTestable) super.clone(); + } } diff --git a/src/cz/crcs/ectester/common/test/CompoundTest.java b/src/cz/crcs/ectester/common/test/CompoundTest.java index 607dadb..ba4ad4f 100644 --- a/src/cz/crcs/ectester/common/test/CompoundTest.java +++ b/src/cz/crcs/ectester/common/test/CompoundTest.java @@ -10,7 +10,7 @@ import java.util.function.Function; * * @author Jan Jancar johny@neuromancer.sk */ -public class CompoundTest extends Test { +public class CompoundTest extends Test implements Cloneable { private Function resultCallback; private Consumer runCallback; private Test[] tests; @@ -206,4 +206,9 @@ public class CompoundTest extends Test { public String getDescription() { return description; } + + @Override + public CompoundTest clone() throws CloneNotSupportedException { + return (CompoundTest) super.clone(); + } } diff --git a/src/cz/crcs/ectester/common/test/SimpleTest.java b/src/cz/crcs/ectester/common/test/SimpleTest.java index 85f1072..d2b3e94 100644 --- a/src/cz/crcs/ectester/common/test/SimpleTest.java +++ b/src/cz/crcs/ectester/common/test/SimpleTest.java @@ -4,11 +4,17 @@ package cz.crcs.ectester.common.test; * @param * @author Jan Jancar johny@neuromancer.sk */ -public abstract class SimpleTest extends Test { +public abstract class SimpleTest extends Test implements Testable { protected T testable; protected TestCallback callback; public SimpleTest(T testable, TestCallback callback) { + if (testable == null) { + throw new IllegalArgumentException("testable is null."); + } + if (callback == null) { + throw new IllegalArgumentException("callback is null."); + } this.testable = testable; this.callback = callback; } @@ -22,4 +28,11 @@ public abstract class SimpleTest extends Test { testable.run(); result = callback.apply(testable); } + + @Override + public SimpleTest clone() throws CloneNotSupportedException { + SimpleTest clone = (SimpleTest) super.clone(); + clone.testable = testable.clone(); + return clone; + } } diff --git a/src/cz/crcs/ectester/common/test/Test.java b/src/cz/crcs/ectester/common/test/Test.java index 055ec1c..8bf9502 100644 --- a/src/cz/crcs/ectester/common/test/Test.java +++ b/src/cz/crcs/ectester/common/test/Test.java @@ -7,7 +7,7 @@ import static cz.crcs.ectester.common.test.Result.Value; * * @author Jan Jancar johny@neuromancer.sk */ -public abstract class Test implements Testable { +public abstract class Test implements Testable, Cloneable { protected boolean hasRun; protected boolean hasStarted; protected Result result; @@ -57,6 +57,11 @@ public abstract class Test implements Testable { public abstract String getDescription(); + @Override + public Test clone() throws CloneNotSupportedException { + return (Test) super.clone(); + } + @Override public void run() { if (hasRun) diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java index 26fdb78..a628d5b 100644 --- a/src/cz/crcs/ectester/common/util/CardUtil.java +++ b/src/cz/crcs/ectester/common/util/CardUtil.java @@ -6,6 +6,9 @@ import javacard.framework.ISO7816; import javacard.security.CryptoException; import javacard.security.KeyPair; +import java.util.LinkedList; +import java.util.List; + /** * @author Petr Svenda petr@svenda.com * @author Jan Jancar johny@neuromancer.sk @@ -183,32 +186,106 @@ public class CardUtil { } } + public static String getParams(short params) { + if (params == 0) { + return ""; + } + List ps = new LinkedList<>(); + short paramMask = EC_Consts.PARAMETER_FP; + while (paramMask <= EC_Consts.PARAMETER_S) { + short paramValue = (short) (paramMask & params); + if (paramValue != 0) { + switch (paramValue) { + case EC_Consts.PARAMETER_FP: + ps.add("P"); + break; + case EC_Consts.PARAMETER_F2M: + ps.add("2^M"); + break; + case EC_Consts.PARAMETER_A: + ps.add("A"); + break; + case EC_Consts.PARAMETER_B: + ps.add("B"); + break; + case EC_Consts.PARAMETER_G: + ps.add("G"); + break; + case EC_Consts.PARAMETER_R: + ps.add("R"); + break; + case EC_Consts.PARAMETER_K: + ps.add("K"); + break; + case EC_Consts.PARAMETER_W: + ps.add("W"); + break; + case EC_Consts.PARAMETER_S: + ps.add("S"); + break; + } + } + paramMask = (short) (paramMask << 1); + } + + if (ps.size() != 0) { + return "[" + String.join(",", ps) + "]"; + } else { + return "unknown"; + } + } + public static String getTransformation(short transformationType) { - switch (transformationType) { - case EC_Consts.TRANSFORMATION_NONE: - return "NONE"; - case EC_Consts.TRANSFORMATION_FIXED: - return "FIXED"; - case EC_Consts.TRANSFORMATION_ONE: - return "ONE"; - case EC_Consts.TRANSFORMATION_ZERO: - return "ZERO"; - case EC_Consts.TRANSFORMATION_ONEBYTERANDOM: - return "ONE_BYTE_RANDOM"; - case EC_Consts.TRANSFORMATION_FULLRANDOM: - return "FULL_RANDOM"; - case EC_Consts.TRANSFORMATION_INCREMENT: - return "INCREMENT"; - case EC_Consts.TRANSFORMATION_INFINITY: - return "INFINITY"; - case EC_Consts.TRANSFORMATION_COMPRESS: - return "COMPRESSED"; - case EC_Consts.TRANSFORMATION_COMPRESS_HYBRID: - return "HYBRID"; - case EC_Consts.TRANSFORMATION_MAX: - return "MAX"; - default: - return "unknown"; + if (transformationType == 0) { + return "NONE"; + } + List names = new LinkedList<>(); + short transformationMask = 1; + while (transformationMask <= EC_Consts.TRANSFORMATION_04_MASK) { + short transformationValue = (short) (transformationMask & transformationType); + if (transformationValue != 0) { + switch (transformationValue) { + case EC_Consts.TRANSFORMATION_FIXED: + names.add("FIXED"); + break; + case EC_Consts.TRANSFORMATION_ONE: + names.add("ONE"); + break; + case EC_Consts.TRANSFORMATION_ZERO: + names.add("ZERO"); + break; + case EC_Consts.TRANSFORMATION_ONEBYTERANDOM: + names.add("ONE_BYTE_RANDOM"); + break; + case EC_Consts.TRANSFORMATION_FULLRANDOM: + names.add("FULL_RANDOM"); + break; + case EC_Consts.TRANSFORMATION_INCREMENT: + names.add("INCREMENT"); + break; + case EC_Consts.TRANSFORMATION_INFINITY: + names.add("INFINITY"); + break; + case EC_Consts.TRANSFORMATION_COMPRESS: + names.add("COMPRESSED"); + break; + case EC_Consts.TRANSFORMATION_COMPRESS_HYBRID: + names.add("HYBRID"); + break; + case EC_Consts.TRANSFORMATION_04_MASK: + names.add("MASK(O4)"); + break; + case EC_Consts.TRANSFORMATION_MAX: + names.add("MAX"); + break; + } + } + transformationMask = (short) ((transformationMask) << 1); + } + if (names.size() != 0) { + return String.join(" + ", names); + } else { + return "unknown"; } } @@ -325,6 +402,8 @@ public class CardUtil { what = "privkey"; } else if (params == EC_Consts.PARAMETERS_KEYPAIR) { what = "keypair"; + } else { + what = getParams(params); } return what; } diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 8af2218..b3af731 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -25,7 +25,7 @@ import java.util.List; /** * @author Jan Jancar johny@neuromancer.sk */ -public abstract class Command { +public abstract class Command implements Cloneable { CommandAPDU cmd; CardMngr cardManager; @@ -49,6 +49,11 @@ public abstract class Command { public abstract String getDescription(); + @Override + protected Command clone() throws CloneNotSupportedException { + return (Command) super.clone(); + } + /** * @param keyPair which keyPair/s (local/remote) to set curve domain parameters on @@ -442,6 +447,7 @@ public abstract class Command { @Override public String getDescription() { + String stringParams = CardUtil.getParams(params); String transform = CardUtil.getTransformation(transformation); String pair; @@ -450,7 +456,7 @@ public abstract class Command { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Transform params of %s, %s", pair, transform); + return String.format("Transform params %s of %s, %s", stringParams, pair, transform); } } diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 6768591..4bf38f2 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -107,8 +107,31 @@ public class CardWrongCurvesSuite extends CardTestSuite { EC_Params compositeData = new EC_Params(EC_Consts.PARAMETER_FP, new byte[][]{compositeBytes}); Test composite = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, compositeData.getParams(), compositeData.flatten()), "Set p = product of two primes.", "ECDH with p = q * s."); - Test wrong = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted prime parameter.", prime0, prime1, primePower, composite); - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Tests of " + keyLength + "b " + CardUtil.getKeyTypeString(KeyPair.ALG_EC_FP), setup, wrong)); + Test wrongPrime = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted prime parameter.", prime0, prime1, primePower, composite); + + Test resetSetup = CompoundTest.all(ExpectedValue.SUCCESS, "Reset keypair.", set.clone()); + + Test zeroG = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = inifnity.", "ECDH with G = infinity."); + Test randomG = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, (short) (EC_Consts.TRANSFORMATION_FULLRANDOM | EC_Consts.TRANSFORMATION_04_MASK)), "Set G = random non-point/point-like.", "ECDH with non-point G."); + Test wrongG = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted G parameter.", zeroG, randomG); + + byte[] originalR = new byte[keyLength]; + EC_Consts.getCurveParameter(curve, EC_Consts.PARAMETER_R, originalR, (short) 0); + BigInteger originalBigR = new BigInteger(1, originalR); + BigInteger nextPrimeR = originalBigR.nextProbablePrime(); + byte[] nextRBytes = ECUtil.toByteArray(nextPrimeR, keyLength); + EC_Params nextRData = new EC_Params(EC_Consts.PARAMETER_R, new byte[][]{nextRBytes}); + Test primeWrongR = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, nextRData.getParams(), nextRData.flatten()), "Set R = some prime (but [r]G != infinity).", "ECDH with wrong R, prime."); + byte[] nonprimeRBytes = nextRBytes.clone(); + nonprimeRBytes[0] ^= 1; + EC_Params nonprimeWrongRData = new EC_Params(EC_Consts.PARAMETER_R, new byte[][]{nonprimeRBytes}); + Test nonprimeWrongR = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, nonprimeWrongRData.getParams(), nonprimeWrongRData.flatten()), "Set R = some composite (but [r]G != infinity).", "ECDH with wrong R, composite."); + + Test wrongR = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted R parameter.", primeWrongR, nonprimeWrongR); + + + + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Tests of " + keyLength + "b " + CardUtil.getKeyTypeString(KeyPair.ALG_EC_FP), setup, wrongPrime, resetSetup, wrongG, resetSetup.clone(), wrongR, resetSetup.clone())); } /* diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index 92a3a27..c223af6 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -233,7 +233,6 @@ public class ECTesterStandalone { System.out.println("\t\t- Curves: " + String.join(", ", curves)); } System.out.println(); - System.out.println(lib.getProvider().entrySet()); } } } -- cgit v1.2.3-70-g09d2 From b6677f491dee8cf93d10b11c0c6e4537f009d6ba Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 3 Jul 2018 14:52:13 +0200 Subject: Better display results in console. --- .../crcs/ectester/common/output/BaseTextTestWriter.java | 15 ++++++++++++--- src/cz/crcs/ectester/reader/command/Command.java | 12 ++++++------ .../crcs/ectester/reader/test/CardInvalidCurvesSuite.java | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src/cz/crcs/ectester/reader/command/Command.java') diff --git a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java index 148466a..8502704 100644 --- a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.common.output; +import cz.crcs.ectester.common.cli.Colors; import cz.crcs.ectester.common.test.*; import java.io.PrintStream; @@ -18,7 +19,7 @@ import java.util.Date; public abstract class BaseTextTestWriter implements TestWriter { private PrintStream output; - public static int BASE_WIDTH = 90; + public static int BASE_WIDTH = 105; public BaseTextTestWriter(PrintStream output) { this.output = output; @@ -56,13 +57,21 @@ public abstract class BaseTextTestWriter implements TestWriter { Result result = t.getResult(); StringBuilder out = new StringBuilder(); - out.append(t.ok() ? " OK " : "NOK "); + out.append(t.ok() ? Colors.ok(" OK ") : Colors.error("NOK ")); out.append(compound ? "┳ " : "━ "); int width = BASE_WIDTH - (prefix.length() + out.length()); String widthSpec = "%-" + String.valueOf(width) + "s"; out.append(String.format(widthSpec, t.getDescription())); out.append(" ┃ "); - out.append(String.format("%-9s", result.getValue().name())); + Colors.Foreground valueColor; + if (result.getValue().ok()) { + valueColor = Colors.Foreground.GREEN; + } else if (result.getValue().equals(Result.Value.ERROR)) { + valueColor = Colors.Foreground.RED; + } else { + valueColor = Colors.Foreground.YELLOW; + } + out.append(Colors.colored(String.format("%-9s", result.getValue().name()), Colors.Attribute.BOLD, valueColor)); out.append(" ┃ "); if (compound) { diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index b3af731..858b05f 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -606,11 +606,11 @@ public abstract class Command implements Cloneable { String validity; if (transformation == EC_Consts.TRANSFORMATION_NONE) { - validity = "unchanged"; + validity = ""; } else { - validity = CardUtil.getTransformation(transformation); + validity = String.format("(%s point)", CardUtil.getTransformation(transformation)); } - return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity); + return String.format("%s of %s pubkey and %s privkey%s", algo, pub, priv, validity); } } @@ -666,11 +666,11 @@ public abstract class Command implements Cloneable { String validity; if (transformation == EC_Consts.TRANSFORMATION_NONE) { - validity = "unchanged"; + validity = ""; } else { - validity = CardUtil.getTransformation(transformation); + validity = String.format("(%s point)", CardUtil.getTransformation(transformation)); } - return String.format("%s of external pubkey and %s privkey(%s point)", algo, priv, validity); + return String.format("%s of external pubkey and %s privkey%s", algo, priv, validity); } } diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index 3c56110..425fa06 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -66,7 +66,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite { } Test ecdsa = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by invalid public points", ecdsaTests.toArray(new Test[0])); - Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, ecdh, ecdsa); + Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test ECDH and ECDSA with points on invalid curves.", ecdh, ecdsa); doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, tests)); new Command.Cleanup(this.card).send(); -- cgit v1.2.3-70-g09d2