aboutsummaryrefslogtreecommitdiff
path: root/reader/src
diff options
context:
space:
mode:
Diffstat (limited to 'reader/src')
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java59
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java20
-rw-r--r--reader/src/test/java/cz/crcs/ectester/reader/AppTests.java71
-rw-r--r--reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java9
4 files changed, 125 insertions, 34 deletions
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java b/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java
index 1fa937e..6a52dc5 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java
@@ -28,6 +28,7 @@ import cz.crcs.ectester.common.cli.CLITools;
import cz.crcs.ectester.common.cli.Colors;
import cz.crcs.ectester.common.ec.EC_Curve;
import cz.crcs.ectester.common.ec.EC_Consts;
+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.*;
@@ -333,6 +334,7 @@ public class ECTesterReader {
opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build());
opts.addOption(Option.builder().longOpt("format").desc("Output format to use. One of: text,yml,xml.").hasArg().argName("format").build());
+ opts.addOption(Option.builder().longOpt("external").desc("Use external key in ECDH.").build());
opts.addOption(Option.builder().longOpt("alloc-keypair").desc("Use KeyPair allocation method, one of: keypair, keybuilder, any.").hasArg().argName("method").build());
opts.addOption(Option.builder().longOpt("fixed").desc("Generate key(s) only once, keep them for later operations.").build());
opts.addOption(Option.builder().longOpt("fixed-private").desc("Generate private key only once, keep it for later ECDH.").build());
@@ -600,10 +602,23 @@ public class ECTesterReader {
Response gen = new Command.Generate(cardManager, CardConsts.KEYPAIR_BOTH).send();
respWriter.outputResponse(gen);
- if (cfg.anyPublicKey || cfg.anyKey) {
- Response prep = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, CardConsts.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W).send();
- respWriter.outputResponse(prep);
+ EC_Params keypair = null;
+ if (!cfg.external) {
+ if (cfg.anyPublicKey || cfg.anyKey) {
+ Response prep = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, CardConsts.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W).send();
+ respWriter.outputResponse(prep);
+ }
+ } else {
+ if (cfg.key != null || cfg.namedKey != null) {
+ keypair = ECUtil.loadParams(EC_Consts.PARAMETERS_KEYPAIR, cfg.namedKey, cfg.key);
+ } else if (cfg.publicKey != null || cfg.namedPublicKey != null) {
+ keypair = ECUtil.loadParams(EC_Consts.PARAMETER_W, cfg.namedPublicKey, cfg.publicKey);
+ } else {
+ System.err.println(Colors.error("No key provided for external ECDH."));
+ return;
+ }
}
+
if (cfg.anyPrivateKey || cfg.anyKey) {
Response prep = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, CardConsts.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S).send();
respWriter.outputResponse(prep);
@@ -633,21 +648,34 @@ public class ECTesterReader {
respWriter.outputResponse(regen);
}
- Response.Export exportRemote = new Command.Export(cardManager, CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W).send();
- respWriter.outputResponse(exportRemote);
- Response.Export exportLocal = new Command.Export(cardManager, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PRIVATE, EC_Consts.PARAMETER_S).send();
- respWriter.outputResponse(exportLocal);
- byte[] pubkey_bytes = exportRemote.getParameter(CardConsts.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W);
- byte[] privkey_bytes = exportLocal.getParameter(CardConsts.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S);
+ byte[] privkey_bytes;
+ byte[] pubkey_bytes;
+ Command perform;
+ if (cfg.external) {
+ Response.Export exportLocal = new Command.Export(cardManager, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PRIVATE, EC_Consts.PARAMETER_S).send();
+ respWriter.outputResponse(exportLocal);
+ privkey_bytes = exportLocal.getParameter(CardConsts.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S);
+ pubkey_bytes = keypair.flatten(EC_Consts.PARAMETER_W);
+
+ perform = new Command.ECDH_direct(cardManager, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType, pubkey_bytes);
+ } else {
+ Response.Export exportRemote = new Command.Export(cardManager, CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W).send();
+ respWriter.outputResponse(exportRemote);
+ Response.Export exportLocal = new Command.Export(cardManager, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PRIVATE, EC_Consts.PARAMETER_S).send();
+ respWriter.outputResponse(exportLocal);
+ pubkey_bytes = exportRemote.getParameter(CardConsts.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W);
+ privkey_bytes = exportLocal.getParameter(CardConsts.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S);
+
+ perform = new Command.ECDH(cardManager, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType);
+ }
- Command.ECDH perform = new Command.ECDH(cardManager, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType);
long time = 0;
if (cfg.time) {
time = -Command.dryRunTime(cardManager, perform, 2, respWriter);
}
- Response.ECDH result = perform.send();
+ Response.ECDH result = (Response.ECDH) perform.send();
respWriter.outputResponse(result);
if (!result.successful() || !result.hasSecret()) {
@@ -842,7 +870,7 @@ public class ECTesterReader {
public boolean fixedKey = false;
public boolean fixedPrivate = false;
public boolean fixedPublic = false;
- public byte keyBuilder;
+ public byte keyBuilder = CardConsts.BUILD_KEYBUILDER | CardConsts.BUILD_KEYPAIR;
public String log;
@@ -859,6 +887,7 @@ public class ECTesterReader {
public boolean color;
//Action-related options
+ public boolean external;
public String listNamed;
public String testSuite;
public int testFrom;
@@ -1080,6 +1109,12 @@ public class ECTesterReader {
}
} else if (cli.hasOption("ecdh")) {
+ external = cli.hasOption("external");
+ if (external && !(anyPublicKey || anyKey)) {
+ System.err.print(Colors.error("Need to specify public key with -pub or -named-public (or key with -key or -named-key) when specifying --external."));
+ return false;
+ }
+
if (primeField == binaryField) {
System.err.print(Colors.error("Need to specify field with -fp or -f2m. (not both)"));
return false;
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
index 28c5e12..ebb71d9 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
@@ -162,9 +162,11 @@ public class CardTestVectorSuite extends CardTestSuite {
}
if (secret.length != derived.length) {
if (secret.length < derived.length) {
- return new Result(Value.FAILURE, String.format("Derived secret was shorter than expected: %d vs %d (expected).", secret.length, derived.length));
+ int diff = ByteUtil.diffBytes(derived, 0, secret, 0, secret.length);
+ return new Result(Value.FAILURE, String.format("Derived secret was shorter than expected: %d vs %d (expected), matched up to byte %d.", secret.length, derived.length, diff));
} else {
- return new Result(Value.FAILURE, String.format("Derived secret was longer than expected: %d vs %d (expected).", secret.length, derived.length));
+ int diff = ByteUtil.diffBytes(derived, 0, secret, 0, derived.length);
+ return new Result(Value.FAILURE, String.format("Derived secret was longer than expected: %d vs %d (expected), matched up to byte %d.", secret.length, derived.length, diff));
}
}
int diff = ByteUtil.diffBytes(derived, 0, secret, 0, secret.length);
@@ -178,8 +180,20 @@ public class CardTestVectorSuite extends CardTestSuite {
}
}
};
+ Test alloc = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.SUCCESS);
Test ecdhTest = CommandTest.function(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), kaCallback);
+ Test ecdh = CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Test DH", alloc, ecdhTest);
+ Test allocRaw = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN), ExpectedValue.SUCCESS);
Test ecdhRawTest = CommandTest.function(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN), kaCallback);
+ Test ecdhRaw = CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Test DH_PLAIN", allocRaw, ecdhRawTest);
+
+ Test allocCofactor = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC), ExpectedValue.SUCCESS);
+ Test ecdhTestCofactor = CommandTest.function(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC), kaCallback);
+ Test ecdhCofactor = CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Test DHC", allocCofactor, ecdhTestCofactor);
+ Test allocRawCofactor = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN), ExpectedValue.SUCCESS);
+ Test ecdhRawTestCofactor = CommandTest.function(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN), kaCallback);
+ Test ecdhRawCofactor = CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Test DHC_PLAIN", allocRawCofactor, ecdhRawTestCofactor);
+
byte[] data = new byte[32];
TestCallback<CommandTestable> sigCallback = new TestCallback<CommandTestable>() {
@Override
@@ -212,7 +226,7 @@ public class CardTestVectorSuite extends CardTestSuite {
}
};
Test ecdsaTest = CommandTest.function(new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, CardConsts.EXPORT_TRUE, data), sigCallback);
- testVector.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test.", ecdhTest, ecdhRawTest, ecdsaTest));
+ testVector.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test.", ecdh, ecdhCofactor, ecdhRaw, ecdhRawCofactor, ecdsaTest)); //
if (cfg.cleanup) {
testVector.add(CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY));
}
diff --git a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java
index 173f7e2..17f43da 100644
--- a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java
+++ b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java
@@ -36,81 +36,98 @@ public class AppTests {
assertTrue(s.contains("secg"));
}
- // Add StdIo to all the suite tests when this is resolved: https://github.com/junit-pioneer/junit-pioneer/issues/822
-
@Test
@XFail(value = "JCardSim sometimes times-out.")
- public void defaultSuite() {
+ @StdIo()
+ public void defaultSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "default", "-s"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
+ @StdIo()
+ public void defaultSuitePart(StdOut out) {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "default:3:5", "-s"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
@Disabled
- public void testVectorSuite() {
+ @StdIo()
+ public void testVectorSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "test-vectors", "-s"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
- public void compressionSuite() {
+ @StdIo()
+ public void compressionSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "compression", "-s"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
@Disabled
- public void wrongSuite() {
+ @StdIo()
+ public void wrongSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "wrong", "-s", "-y"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
- public void degenerateSuite() {
+ @StdIo()
+ public void degenerateSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "degenerate", "-s", "-y"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
@Disabled
- public void cofactorSuite() {
+ @StdIo()
+ public void cofactorSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "cofactor", "-s", "-y"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
@Disabled
- public void compositeSuite() {
+ @StdIo()
+ public void compositeSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "composite", "-s", "-y"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
- public void invalidSuite() {
+ @StdIo()
+ public void invalidSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "invalid", "-s", "-y"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
- public void edgeCasesSuite() {
+ @StdIo()
+ public void edgeCasesSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "edge-cases", "-s", "-y"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
- public void signatureSuite() {
+ @StdIo()
+ public void signatureSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "signature", "-s"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
- public void twistSuite() {
+ @StdIo()
+ public void twistSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "twist", "-s", "-y"}));
}
@Test
@XFail(value = "JCardSim sometimes times-out.")
- public void miscellaneousSuite() {
+ @StdIo()
+ public void miscellaneousSuite(StdOut out) {
assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "miscellaneous", "-s", "-y"}));
}
@@ -120,22 +137,40 @@ public class AppTests {
}
@Test
- public void ecdh() {
+ @StdIo()
+ public void ecdh(StdOut out) {
ECTesterReader.main(new String[]{"-dh", "-fp", "-b", "256", "-s"});
+ String s = out.capturedString();
+ assertTrue(s.contains("OK"));
+ assertTrue(s.contains("ALG_EC_SVDP_DH of remote pubkey and local privkey"));
+ }
+
+ @Test
+ @StdIo()
+ public void ecdh_external(StdOut out) {
+ ECTesterReader.main(new String[]{"-dh", "-fp", "--external", "--named-curve", "secg/secp256r1", "--named-public", "invalid/secp256r1/0", "-b", "256", "-s"});
+ String s = out.capturedString();
+ assertTrue(s.contains("OK"));
+ assertTrue(s.contains("ALG_EC_SVDP_DH of external pubkey and local privkey"));
}
@Test
- public void ecdsa() {
+ @StdIo()
+ public void ecdsa(StdOut out) {
ECTesterReader.main(new String[]{"-dsa", "-fp", "-b", "256", "-s"});
+ String s = out.capturedString();
+ System.err.println(s);
}
@Test
- public void export() {
+ @StdIo()
+ public void export(StdOut out) {
ECTesterReader.main(new String[]{"-e", "-fp", "-b", "256", "-s", "-o", "/dev/null"});
}
@Test
- public void info() {
+ @StdIo()
+ public void info(StdOut out) {
ECTesterReader.main(new String[]{"-nf", "-s"});
}
}
diff --git a/reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java b/reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java
index 5300e98..5d7ba95 100644
--- a/reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java
+++ b/reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java
@@ -1,13 +1,20 @@
package cz.crcs.ectester.reader;
+import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
+import java.nio.file.Path;
+
public class OutputTests {
+ @TempDir
+ static Path tempDir;
+
@ParameterizedTest
@ValueSource(strings = {"text", "xml", "yml"})
public void formats(String format) {
- ECTesterReader.main(new String[]{"-t", "default", "-s", "-o", String.format("%s:out.%s", format, format),});
+ Path outputFile = tempDir.resolve(String.format("out.%s", format));
+ ECTesterReader.main(new String[]{"-t", "default", "-s", "-o", String.format("%s:%s", format, outputFile),});
}
}