summaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/reader
diff options
context:
space:
mode:
authorJ08nY2018-10-15 18:16:03 +0200
committerJ08nY2018-10-15 18:16:03 +0200
commitee13937d70383e925cf32858e73d89a6c18bf7f0 (patch)
treefa3f8dfd255b8a24d15dd1734fe327df56b8ac2c /src/cz/crcs/ectester/reader
parentd24630d759bb16f715564ab80a5d4447f57d03f2 (diff)
parentea4e807906815c16c62c4e5719950c7274d1ebab (diff)
downloadECTester-ee13937d70383e925cf32858e73d89a6c18bf7f0.tar.gz
ECTester-ee13937d70383e925cf32858e73d89a6c18bf7f0.tar.zst
ECTester-ee13937d70383e925cf32858e73d89a6c18bf7f0.zip
Merge branch 'devel'
Diffstat (limited to 'src/cz/crcs/ectester/reader')
-rw-r--r--src/cz/crcs/ectester/reader/ECTesterReader.java28
-rw-r--r--src/cz/crcs/ectester/reader/command/Command.java34
-rw-r--r--src/cz/crcs/ectester/reader/output/FileTestWriter.java2
-rw-r--r--src/cz/crcs/ectester/reader/output/YAMLTestWriter.java5
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCofactorSuite.java33
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCompositeSuite.java10
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCompressionSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardDefaultSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java9
-rw-r--r--src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java113
-rw-r--r--src/cz/crcs/ectester/reader/test/CardInvalidSuite.java31
-rw-r--r--src/cz/crcs/ectester/reader/test/CardMiscSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardSignatureSuite.java68
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTwistSuite.java28
-rw-r--r--src/cz/crcs/ectester/reader/test/CommandTest.java19
-rw-r--r--src/cz/crcs/ectester/reader/test/PerformanceTest.java1
17 files changed, 274 insertions, 115 deletions
diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java
index 4a7d779..5c50bf2 100644
--- a/src/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/src/cz/crcs/ectester/reader/ECTesterReader.java
@@ -26,7 +26,6 @@ import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.common.cli.CLITools;
import cz.crcs.ectester.common.cli.Colors;
-import cz.crcs.ectester.common.ec.EC_Params;
import cz.crcs.ectester.common.output.OutputLogger;
import cz.crcs.ectester.common.output.TestWriter;
import cz.crcs.ectester.common.util.ByteUtil;
@@ -94,7 +93,6 @@ public class ECTesterReader {
DESCRIPTION = "ECTesterReader " + VERSION + GIT_COMMIT + ", a javacard Elliptic Curve Cryptography support tester/utility.";
CLI_HEADER = "\n" + DESCRIPTION + "\n\n";
- ;
}
private void run(String[] args) {
@@ -276,18 +274,14 @@ public class ECTesterReader {
actions.addOption(Option.builder("ln").longOpt("list-named").desc("Print the list of supported named curves and keys.").hasArg().argName("what").optionalArg(true).build());
actions.addOption(Option.builder("e").longOpt("export").desc("Export the defaut curve parameters of the card(if any).").build());
actions.addOption(Option.builder("g").longOpt("generate").desc("Generate <amount> of EC keys.").hasArg().argName("amount").optionalArg(true).build());
- actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. Optionally specify a test number to run only a part of a test suite. <test_suite>:\n- default:\n- compression:\n- invalid:\n- twist:\n- degenerate:\n- cofactor:\n- wrong:\n- composite:\n- test-vectors:\n- edge-cases:\n- miscellaneous:").hasArg().argName("test_suite[:from[:to]]").optionalArg(true).build());
+ actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. Optionally specify a test number to run only a part of a test suite. <test_suite>:\n- default:\n- compression:\n- invalid:\n- twist:\n- degenerate:\n- cofactor:\n- wrong:\n- signature:\n- composite:\n- test-vectors:\n- edge-cases:\n- miscellaneous:").hasArg().argName("test_suite[:from[:to]]").optionalArg(true).build());
actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do EC KeyAgreement (ECDH...), [count] times.").hasArg().argName("count").optionalArg(true).build());
actions.addOption(Option.builder("dsa").longOpt("ecdsa").desc("Sign data with ECDSA, [count] times.").hasArg().argName("count").optionalArg(true).build());
actions.addOption(Option.builder("ls").longOpt("list-suites").desc("List supported test suites.").build());
opts.addOptionGroup(actions);
- OptionGroup size = new OptionGroup();
- size.addOption(Option.builder("b").longOpt("bit-size").desc("Set curve size.").hasArg().argName("bits").build());
- size.addOption(Option.builder("a").longOpt("all").desc("Test all curve sizes.").build());
- opts.addOptionGroup(size);
-
+ opts.addOption(Option.builder("b").longOpt("bit-size").desc("Set curve size.").hasArg().argName("bits").build());
opts.addOption(Option.builder("fp").longOpt("prime-field").desc("Use a prime field.").build());
opts.addOption(Option.builder("f2m").longOpt("binary-field").desc("Use a binary field.").build());
@@ -342,6 +336,7 @@ public class ECTesterReader {
new CardCompositeSuite(null, null, null),
new CardInvalidSuite(null, null, null),
new CardEdgeCasesSuite(null, null, null),
+ new CardSignatureSuite(null, null, null),
new CardTwistSuite(null, null, null),
new CardMiscSuite(null, null, null)};
for (CardTestSuite suite : suites) {
@@ -363,9 +358,15 @@ public class ECTesterReader {
List<Response> sent = new LinkedList<>();
sent.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send());
- sent.add(new Command.Clear(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send());
+ //sent.add(new Command.Clear(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send());
sent.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send());
+ // Also support exporting set parameters, to verify they are set correctly.
+ Command curve = Command.prepareCurve(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass);
+ if (curve != null) {
+ sent.add(curve.send());
+ }
+
// Cofactor generally isn't set on the default curve parameters on cards,
// since its not necessary for ECDH, only ECDHC which not many cards implement
// TODO: check if its assumend to be == 1?
@@ -476,6 +477,9 @@ public class ECTesterReader {
case "miscellaneous":
suite = new CardMiscSuite(writer, cfg, cardManager);
break;
+ case "signature":
+ suite = new CardSignatureSuite(writer, cfg, cardManager);
+ break;
default:
// These run are dangerous, prompt before them.
System.out.println("The test you selected (" + cfg.testSuite + ") is potentially dangerous.");
@@ -804,10 +808,6 @@ public class ECTesterReader {
System.err.println(Colors.error("Keys should not be specified when exporting curve params."));
return false;
}
- if (namedCurve != null || customCurve || curveFile != null) {
- System.err.println(Colors.error("Specifying a curve for curve export makes no sense."));
- return false;
- }
if (outputs == null) {
System.err.println(Colors.error("You have to specify an output file for curve parameter export."));
return false;
@@ -873,7 +873,7 @@ public class ECTesterReader {
testFrom = 0;
testTo = -1;
}
- String[] tests = new String[]{"default", "composite", "compression", "invalid", "degenerate", "test-vectors", "wrong", "twist", "cofactor", "edge-cases", "miscellaneous"};
+ String[] tests = new String[]{"default", "composite", "compression", "invalid", "degenerate", "test-vectors", "wrong", "twist", "cofactor", "edge-cases", "miscellaneous", "signature"};
if (!Arrays.asList(tests).contains(testSuite)) {
System.err.println(Colors.error("Unknown test suite " + testSuite + ". Should be one of: " + Arrays.toString(tests)));
return false;
diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java
index 858b05f..5a4af21 100644
--- a/src/cz/crcs/ectester/reader/command/Command.java
+++ b/src/cz/crcs/ectester/reader/command/Command.java
@@ -417,11 +417,11 @@ public abstract class Command implements Cloneable {
private short transformation;
/**
- * @param cardManager cardManager to send APDU through
- * @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_*)
+ * @param cardManager cardManager to send APDU through
+ * @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 Transform(CardMngr cardManager, byte keyPair, byte key, short params, short transformation) {
super(cardManager);
@@ -568,12 +568,12 @@ public abstract class Command implements Cloneable {
/**
* Creates the INS_ECDH instruction.
*
- * @param cardManager cardManager to send APDU through
- * @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 transformation whether to transform the pubkey before ECDH (EC_Consts.TRANSFORMATION_* | ...)
- * @param type ECDH algorithm type (EC_Consts.KA_* | ...)
+ * @param cardManager cardManager to send APDU through
+ * @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 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 transformation, byte type) {
super(cardManager);
@@ -627,12 +627,12 @@ public abstract class Command implements Cloneable {
/**
* Creates the INS_ECDH_DIRECT instruction.
*
- * @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 transformation whether to transform the pubkey before ECDH (EC_Consts.TRANSFORMATION_* | ...)
- * @param type EC KeyAgreement type
- * @param pubkey pubkey data to do ECDH with.
+ * @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 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 transformation, byte type, byte[] pubkey) {
super(cardManager);
diff --git a/src/cz/crcs/ectester/reader/output/FileTestWriter.java b/src/cz/crcs/ectester/reader/output/FileTestWriter.java
index e4ef9b8..69e5f41 100644
--- a/src/cz/crcs/ectester/reader/output/FileTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/FileTestWriter.java
@@ -26,7 +26,7 @@ public class FileTestWriter extends TeeTestWriter {
String fName = files[i];
String format = null;
if (PREFIX.matcher(fName).matches()) {
- String[] split = fName.split(":",2);
+ String[] split = fName.split(":", 2);
format = split[0];
fName = split[1];
}
diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
index 080fa8b..7c99a4a 100644
--- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
@@ -13,7 +13,10 @@ import cz.crcs.ectester.reader.test.CommandTestable;
import javax.smartcardio.CardException;
import java.io.PrintStream;
-import java.util.*;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
/**
* @author Jan Jancar johny@neuromancer.sk
diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
index 39024b8..710b704 100644
--- a/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
@@ -6,7 +6,9 @@ import cz.crcs.ectester.common.ec.EC_Curve;
import cz.crcs.ectester.common.ec.EC_Key;
import cz.crcs.ectester.common.output.TestWriter;
import cz.crcs.ectester.common.test.CompoundTest;
+import cz.crcs.ectester.common.test.Result;
import cz.crcs.ectester.common.test.Test;
+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;
@@ -15,7 +17,6 @@ import cz.crcs.ectester.reader.command.Command;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Random;
import static cz.crcs.ectester.common.test.Result.ExpectedValue;
@@ -43,34 +44,20 @@ public class CardCofactorSuite extends CardTestSuite {
List<Test> ecdhTests = new LinkedList<>();
for (EC_Key.Public pub : keys) {
+ Test setPub = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.ExpectedValue.FAILURE);
+ Test ecdh = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE);
+ Test objectEcdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with degenerate pubkey.", setPub, ecdh);
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 non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup."));
+ Test rawEcdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup.");
+ ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " cofactor key test.", objectEcdh, rawEcdh));
}
Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with public points on non-generator subgroup.", ecdhTests.toArray(new Test[0]));
- Random r = new Random();
- byte[] raw = new byte[128];
- byte[] sig = new byte[40];
- r.nextBytes(raw);
- r.nextBytes(sig);
-
- List<Test> ecdsaTests = new LinkedList<>();
- for (EC_Key.Public pub : keys) {
- Command setCommand = new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten());
- Test setTest = CommandTest.expect(setCommand, ExpectedValue.ANY);
- Command ecdsaCommand = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.Signature_ALG_ECDSA_SHA, raw, sig);
- Test ecdsaTest = CommandTest.expect(ecdsaCommand, ExpectedValue.FAILURE);
- ecdsaTests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Verify random ECDSA signature by " + pub.getId() + ".", setTest, ecdsaTest));
- }
- Test ecdsa = CompoundTest.all(ExpectedValue.SUCCESS, "Verify random ECDSA signature by public points on non-generator subgroup.", ecdsaTests.toArray(new Test[0]));
-
- Test tests = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH and ECDSA tests.", ecdh, ecdsa);
-
if (cfg.cleanup) {
- Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.SUCCESS);
- doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId() + ".", prepare, tests, cleanup));
+ Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY);
+ doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId() + ".", prepare, ecdh, cleanup));
} else {
- doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId() + ".", prepare, tests));
+ doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId() + ".", prepare, ecdh));
}
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
index ec56901..336b371 100644
--- a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
@@ -97,6 +97,7 @@ public class CardCompositeSuite extends CardTestSuite {
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_BOTH), ExpectedValue.ANY);
Test ecdh = 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), dhValue, ok, nok);
+ Test ecdsa = CommandTest.expect(new Command.ECDSA(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, ECTesterApplet.EXPORT_FALSE, null), dhValue, ok, nok);
String description;
if (testName == null) {
@@ -104,11 +105,14 @@ public class CardCompositeSuite extends CardTestSuite {
} else {
description = testName + " test of " + curve.getId() + ".";
}
+
+ Test perform = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH and ECDSA.", ecdh, ecdsa);
+
if (cfg.cleanup) {
- Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.SUCCESS);
- doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, description, allocate, set, generate, ecdh, cleanup));
+ Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY);
+ doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, description, allocate, set, generate, perform, cleanup));
} else {
- doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, description, allocate, set, generate, ecdh));
+ doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, description, allocate, set, generate, perform));
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
index 5e8f600..ae25bf1 100644
--- a/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
@@ -113,7 +113,7 @@ public class CardCompressionSuite extends CardTestSuite {
}
compressionTests.addAll(kaTests);
if (cfg.cleanup) {
- compressionTests.add(CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.SUCCESS));
+ compressionTests.add(CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY));
}
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Compression test of " + spec + ".", compressionTests.toArray(new Test[0])));
diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
index fa9bfd0..e495b00 100644
--- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
@@ -131,7 +131,7 @@ public class CardDefaultSuite extends CardTestSuite {
ExpectedValue[] testExpects = {ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS};
List<ExpectedValue> expects = Stream.of(testExpects).collect(Collectors.toList());
if (cfg.cleanup) {
- supportTests.add(CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.SUCCESS));
+ supportTests.add(CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY));
expects.add(ExpectedValue.ANY);
}
diff --git a/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java b/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
index 064c6cb..c926a4d 100644
--- a/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
@@ -8,6 +8,7 @@ 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.util.CardUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
@@ -43,12 +44,16 @@ public class CardDegenerateSuite extends CardTestSuite {
List<Test> ecdhTests = new LinkedList<>();
for (EC_Key.Public pub : keys) {
+ Test setPub = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.ExpectedValue.FAILURE);
+ Test ecdh = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE);
+ Test objectEcdh = CompoundTest.any(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with degenerate pubkey.", setPub, ecdh);
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 degenerate curve.", "Card incorrectly accepted point on degenerate curve."));
+ Test rawEcdh = CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on degenerate curve.", "Card incorrectly accepted point on degenerate curve.");
+ ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " degenerate key test.", objectEcdh, rawEcdh));
}
Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with degenerate public points", ecdhTests.toArray(new Test[0]));
if (cfg.cleanup) {
- Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.SUCCESS);
+ Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId(), prepare, ecdh, cleanup));
} else {
doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId(), prepare, ecdh));
diff --git a/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java b/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
index dc489a0..b68b2ec 100644
--- a/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
@@ -21,11 +21,9 @@ import cz.crcs.ectester.reader.response.Response;
import javacard.security.CryptoException;
import javacard.security.KeyPair;
+import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
+import java.util.*;
import java.util.stream.Collectors;
/**
@@ -112,8 +110,37 @@ public class CardEdgeCasesSuite extends CardTestSuite {
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, description, groupTests.toArray(new Test[0])));
}
+ {
+ EC_KAResult openssl_bug = EC_Store.getInstance().getObject(EC_KAResult.class, "other", "openssl-bug");
+ EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, openssl_bug.getCurve());
+ EC_Key.Private skey = EC_Store.getInstance().getObject(EC_Key.Private.class, openssl_bug.getOtherKey());
+ EC_Key.Public pkey = EC_Store.getInstance().getObject(EC_Key.Public.class, openssl_bug.getOneKey());
+ Test key = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), KeyPair.ALG_EC_FP), Result.ExpectedValue.SUCCESS);
+ Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
+ Test setPrivate = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, skey.flatten(EC_Consts.PARAMETER_S)), Result.ExpectedValue.SUCCESS);
+ Test setPublic = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, pkey.flatten(EC_Consts.PARAMETER_W)), Result.ExpectedValue.SUCCESS);
+ Test ecdh = CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, openssl_bug.getJavaCardKA()), new TestCallback<CommandTestable>() {
+ @Override
+ public Result apply(CommandTestable testable) {
+ Response.ECDH dh = (Response.ECDH) testable.getResponse();
+ if (!dh.successful())
+ return new Result(Result.Value.FAILURE, "ECDH was unsuccessful.");
+ if (!dh.hasSecret())
+ return new Result(Result.Value.FAILURE, "ECDH response did not contain the derived secret.");
+ if (ByteUtil.compareBytes(dh.getSecret(), 0, openssl_bug.getData(0), 0, dh.secretLength())) {
+ return new Result(Result.Value.FAILURE, "OpenSSL bug is present, derived secret matches example.");
+ }
+ return new Result(Result.Value.SUCCESS);
+ }
+ });
+
+ doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Test OpenSSL modular reduction bug.", key, set, setPrivate, setPublic, ecdh));
+ }
+
Map<String, EC_Curve> curveMap = EC_Store.getInstance().getObjects(EC_Curve.class, "secg");
List<EC_Curve> curves = curveMap.entrySet().stream().filter((e) -> e.getKey().endsWith("r1") && e.getValue().getField() == KeyPair.ALG_EC_FP).map(Map.Entry::getValue).collect(Collectors.toList());
+ curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor128p2"));
+ curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor160p4"));
Random rand = new Random();
for (EC_Curve curve : curves) {
Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), KeyPair.ALG_EC_FP), Result.ExpectedValue.SUCCESS));
@@ -128,13 +155,18 @@ public class CardEdgeCasesSuite extends CardTestSuite {
Test zeroS = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, EC_Consts.TRANSFORMATION_ZERO), "ECDH with S = 0.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
Test oneS = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, EC_Consts.TRANSFORMATION_ONE), "ECDH with S = 1.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
- byte[] r = curve.getParam(EC_Consts.PARAMETER_R)[0];
- BigInteger R = new BigInteger(1, r);
+ byte[] rParam = curve.getParam(EC_Consts.PARAMETER_R)[0];
+ BigInteger R = new BigInteger(1, rParam);
BigInteger smaller = new BigInteger(curve.getBits(), rand).mod(R);
BigInteger diff = R.divide(BigInteger.valueOf(10));
BigInteger randDiff = new BigInteger(diff.bitLength(), rand).mod(diff);
BigInteger larger = R.add(randDiff);
+ BigInteger full = BigInteger.valueOf(1).shiftLeft(R.bitLength() - 1).subtract(BigInteger.ONE);
+
+ EC_Params fullParams = makeParams(full);
+ Test fullS = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, fullParams.getParams(), fullParams.flatten()), "ECDH with S = 2^((log2 r) - 1) - 1.", Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
+
EC_Params smallerParams = makeParams(smaller);
Test smallerS = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, smallerParams.getParams(), smallerParams.flatten()), "ECDH with S < r.", Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
@@ -168,8 +200,75 @@ public class CardEdgeCasesSuite extends CardTestSuite {
EC_Params krp1Params = makeParams(krp1);
Test krp1S = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, krp1Params.getParams(), krp1Params.flatten()), "ECDH with S = (k * r) + 1.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".", setup, zeroS, oneS, smallerS, exactS, largerS, rm1S, rp1S, krS, krm1S, krp1S));
+ if (cfg.cleanup) {
+ Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".", setup, zeroS, oneS, fullS, smallerS, exactS, largerS, rm1S, rp1S, krS, krm1S, krp1S, cleanup));
+ } else {
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".", setup, zeroS, oneS, fullS, smallerS, exactS, largerS, rm1S, rp1S, krS, krm1S, krp1S));
+ }
+ }
+
+ EC_Curve secp160r1 = EC_Store.getInstance().getObject(EC_Curve.class, "secg/secp160r1");
+ byte[] pData = secp160r1.getParam(EC_Consts.PARAMETER_FP)[0];
+ BigInteger p = new BigInteger(1, pData);
+ byte[] rData = secp160r1.getParam(EC_Consts.PARAMETER_R)[0];
+ BigInteger r = new BigInteger(1, rData);
+
+ BigInteger range = r.subtract(p);
+ BigInteger deviation = range.divide(BigInteger.valueOf(5));
+ BigDecimal dev = new BigDecimal(deviation);
+ BigDecimal smallDev = new BigDecimal(10000);
+ int n = 10;
+ BigInteger[] rs = new BigInteger[n];
+ BigInteger[] ps = new BigInteger[n];
+ BigInteger[] zeros = new BigInteger[n];
+ for (int i = 0; i < n; ++i) {
+ double sample;
+ do {
+ sample = rand.nextGaussian();
+ } while (sample >= -1 && sample <= 1);
+ BigInteger where = dev.multiply(new BigDecimal(sample)).toBigInteger();
+ rs[i] = where.add(r);
+ ps[i] = where.add(p);
+ zeros[i] = smallDev.multiply(new BigDecimal(sample)).toBigInteger().abs();
+ }
+ Arrays.sort(rs);
+ Arrays.sort(ps);
+ Arrays.sort(zeros);
+
+ Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, secp160r1.getBits(), KeyPair.ALG_EC_FP), Result.ExpectedValue.SUCCESS));
+ if (!key.ok()) {
+ doTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "No support for " + secp160r1.getBits() + "b ALG_EC_FP.", key));
+ return;
+ }
+ Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, secp160r1.getParams(), secp160r1.flatten()), Result.ExpectedValue.SUCCESS);
+ Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS);
+ Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate);
+
+ Test[] zeroTests = new Test[n];
+ int i = 0;
+ for (BigInteger nearZero : zeros) {
+ EC_Params params = makeParams(nearZero);
+ zeroTests[i++] = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearZero.toString(16), Result.ExpectedValue.ANY, Result.ExpectedValue.ANY);
+ }
+ Test zeroTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near zero.", zeroTests);
+
+ Test[] pTests = new Test[n];
+ i = 0;
+ for (BigInteger nearP : ps) {
+ EC_Params params = makeParams(nearP);
+ pTests[i++] = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearP.toString(16) + (nearP.compareTo(p) > 0 ? " (>p)" : " (<=p)"), Result.ExpectedValue.ANY, Result.ExpectedValue.ANY);
+ }
+ Test pTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near p.", pTests);
+
+ Test[] rTests = new Test[n];
+ i = 0;
+ for (BigInteger nearR : rs) {
+ EC_Params params = makeParams(nearR);
+ rTests[i++] = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearR.toString(16) + (nearR.compareTo(r) > 0 ? " (>r)" : " (<=r)"), Result.ExpectedValue.ANY, Result.ExpectedValue.ANY);
}
+ Test rTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near r.", rTests);
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test private key values near zero, near p and near/larger than the order.", setup, zeroTest, pTest, rTest));
}
private Test ecdhTest(Command setPriv, String desc, Result.ExpectedValue setExpect, Result.ExpectedValue ecdhExpect) {
diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java
index 59a427f..17c5d4b 100644
--- a/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java
@@ -8,6 +8,7 @@ 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.util.CardUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
@@ -16,7 +17,6 @@ import cz.crcs.ectester.reader.command.Command;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Random;
import static cz.crcs.ectester.common.test.Result.ExpectedValue;
@@ -48,33 +48,20 @@ public class CardInvalidSuite extends CardTestSuite {
List<Test> ecdhTests = new LinkedList<>();
for (EC_Key.Public pub : keys) {
+ Test setPub = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.ExpectedValue.FAILURE);
+ Test ecdh = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE);
+ Test objectEcdh = CompoundTest.any(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with invalid pubkey.", setPub, ecdh);
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 rawEcdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.");
+ ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", objectEcdh, rawEcdh));
}
Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0]));
- Random r = new Random();
- byte[] raw = new byte[128];
- byte[] sig = new byte[40];
- r.nextBytes(raw);
- r.nextBytes(sig);
-
- List<Test> ecdsaTests = new LinkedList<>();
- for (EC_Key.Public pub : keys) {
- Command setCommand = new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten());
- Test setTest = CommandTest.expect(setCommand, Result.ExpectedValue.ANY);
- Command ecdsaCommand = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.Signature_ALG_ECDSA_SHA, raw, sig);
- Test ecdsaTest = CommandTest.expect(ecdsaCommand, Result.ExpectedValue.FAILURE);
- ecdsaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by " + pub.getId(), setTest, ecdsaTest));
- }
- 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, "Test ECDH and ECDSA with points on invalid curves.", ecdh, ecdsa);
if (cfg.cleanup) {
- Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.SUCCESS);
- doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, tests, cleanup));
+ Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY);
+ doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, ecdh, cleanup));
} else {
- doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, tests));
+ doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, ecdh));
}
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CardMiscSuite.java b/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
index e568f67..8623e36 100644
--- a/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
@@ -50,7 +50,7 @@ public class CardMiscSuite extends CardTestSuite {
Test perform = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH and ECDSA", ka, sig);
if (cfg.cleanup) {
- Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.SUCCESS);
+ Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + " " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform, cleanup));
} else {
doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + " " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform));
diff --git a/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java b/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java
new file mode 100644
index 0000000..59def74
--- /dev/null
+++ b/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java
@@ -0,0 +1,68 @@
+package cz.crcs.ectester.reader.test;
+
+import cz.crcs.ectester.applet.ECTesterApplet;
+import cz.crcs.ectester.applet.EC_Consts;
+import cz.crcs.ectester.common.ec.EC_Curve;
+import cz.crcs.ectester.common.ec.EC_Key;
+import cz.crcs.ectester.common.ec.EC_SigResult;
+import cz.crcs.ectester.common.output.TestWriter;
+import cz.crcs.ectester.common.test.CompoundTest;
+import cz.crcs.ectester.common.test.Result;
+import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.data.EC_Store;
+import cz.crcs.ectester.reader.CardMngr;
+import cz.crcs.ectester.reader.ECTesterReader;
+import cz.crcs.ectester.reader.command.Command;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class CardSignatureSuite extends CardTestSuite {
+ public CardSignatureSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) {
+ super(writer, cfg, cardManager, "signature", "Test verifying various wrong ECDSA values.");
+ }
+
+ @Override
+ protected void runTests() throws Exception {
+ Map<String, EC_SigResult> results = EC_Store.getInstance().getObjects(EC_SigResult.class, "wrong");
+ List<Map.Entry<String, List<EC_SigResult>>> groupList = EC_Store.mapToPrefix(results.values());
+
+ List<EC_SigResult> nok = groupList.stream().filter((e) -> e.getKey().equals("nok")).findFirst().get().getValue();
+
+ byte[] data = "Some stuff that is not the actual data".getBytes();
+ for (EC_SigResult sig : nok) {
+ ecdsaTest(sig, Result.ExpectedValue.FAILURE, data);
+ }
+
+ List<EC_SigResult> ok = groupList.stream().filter((e) -> e.getKey().equals("ok")).findFirst().get().getValue();
+ for (EC_SigResult sig : ok) {
+ ecdsaTest(sig, Result.ExpectedValue.SUCCESS, null);
+ }
+ }
+
+ private void ecdsaTest(EC_SigResult sig, Result.ExpectedValue expected, byte[] defaultData) {
+ EC_Key.Public pubkey = EC_Store.getInstance().getObject(EC_Key.Public.class, sig.getVerifyKey());
+
+ byte[] data = sig.getSigData();
+ if (data == null) {
+ data = defaultData;
+ }
+
+ EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, sig.getCurve());
+ Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS);
+ Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
+ Test setVerifyKey = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, pubkey.getParams(), pubkey.flatten()), Result.ExpectedValue.SUCCESS);
+ Test ecdsaVerify = CommandTest.expect(new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_LOCAL, sig.getJavaCardSig(), data, sig.getData(0)), expected);
+
+ if (cfg.cleanup) {
+ Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "ECDSA test of " + sig.getId() + ".", allocate, set, setVerifyKey, ecdsaVerify, cleanup));
+ } else {
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "ECDSA test of " + sig.getId() + ".", allocate, set, setVerifyKey, ecdsaVerify));
+ }
+
+ }
+}
diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
index 052e480..fbdf103 100644
--- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
@@ -73,7 +73,7 @@ public class CardTestVectorSuite extends CardTestSuite {
}
}));
if (cfg.cleanup) {
- testVector.add(CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.SUCCESS));
+ testVector.add(CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY));
}
doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0])));
}
diff --git a/src/cz/crcs/ectester/reader/test/CardTwistSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistSuite.java
index 1e1f5f3..6ad4ce6 100644
--- a/src/cz/crcs/ectester/reader/test/CardTwistSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTwistSuite.java
@@ -8,6 +8,7 @@ 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.util.CardUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
@@ -16,7 +17,6 @@ import cz.crcs.ectester.reader.command.Command;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Random;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -42,30 +42,18 @@ public class CardTwistSuite extends CardTestSuite {
List<Test> ecdhTests = new LinkedList<>();
for (EC_Key.Public pub : keys) {
+ Test setPub = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.ExpectedValue.FAILURE);
+ Test ecdh = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE);
+ Test objectEcdh = CompoundTest.any(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with twist pubkey.", setPub, ecdh);
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 rawEcdh = CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.");
+ ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " twist key test.", objectEcdh, rawEcdh));
}
Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0]));
- Random r = new Random();
- byte[] raw = new byte[128];
- byte[] sig = new byte[40];
- r.nextBytes(raw);
- r.nextBytes(sig);
-
- List<Test> ecdsaTests = new LinkedList<>();
- for (EC_Key.Public pub : keys) {
- Command setCommand = new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten());
- Test setTest = CommandTest.expect(setCommand, Result.ExpectedValue.ANY);
- Command ecdsaCommand = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.Signature_ALG_ECDSA_SHA, raw, sig);
- Test ecdsaTest = CommandTest.expect(ecdsaCommand, Result.ExpectedValue.FAILURE);
- ecdsaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by " + pub.getId(), setTest, ecdsaTest));
- }
- Test ecdsa = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by public points on twist", ecdsaTests.toArray(new Test[0]));
-
- Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, ecdh, ecdsa);
+ Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", ecdh);
if (cfg.cleanup) {
- Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.SUCCESS);
+ Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), prepare, tests, cleanup));
} else {
doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), prepare, tests));
diff --git a/src/cz/crcs/ectester/reader/test/CommandTest.java b/src/cz/crcs/ectester/reader/test/CommandTest.java
index d57dc17..adad191 100644
--- a/src/cz/crcs/ectester/reader/test/CommandTest.java
+++ b/src/cz/crcs/ectester/reader/test/CommandTest.java
@@ -6,6 +6,8 @@ import cz.crcs.ectester.common.test.TestCallback;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.response.Response;
+import java.util.Arrays;
+
/**
* A simple test that runs one Command to get and evaluate one Response
* to get a Result and compare it with the expected one.
@@ -47,6 +49,23 @@ public class CommandTest extends SimpleTest<CommandTestable> {
return expect(command, expectedValue, null, null);
}
+ public static CommandTest expectSW(CommandTestable command, short... expectedSWS) {
+ return new CommandTest(command, new TestCallback<CommandTestable>() {
+ @Override
+ public Result apply(CommandTestable commandTestable) {
+ if (Arrays.equals(commandTestable.getResponse().getSWs(), expectedSWS)) {
+ return new Result(Result.Value.SUCCESS);
+ } else {
+ return new Result(Result.Value.FAILURE);
+ }
+ }
+ });
+ }
+
+ public static CommandTest expectSW(Command command, short... expectedSWS) {
+ return expectSW(new CommandTestable(command), expectedSWS);
+ }
+
public Command getCommand() {
return testable.getCommand();
}
diff --git a/src/cz/crcs/ectester/reader/test/PerformanceTest.java b/src/cz/crcs/ectester/reader/test/PerformanceTest.java
index 9abaadc..f9a4472 100644
--- a/src/cz/crcs/ectester/reader/test/PerformanceTest.java
+++ b/src/cz/crcs/ectester/reader/test/PerformanceTest.java
@@ -3,7 +3,6 @@ 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;