diff options
Diffstat (limited to 'reader/src')
16 files changed, 481 insertions, 191 deletions
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java b/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java index 892a481..2bd4c77 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java @@ -19,6 +19,7 @@ import javax.smartcardio.ResponseAPDU; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java index a28c2a7..bba211a 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java @@ -36,13 +36,8 @@ public class CardCompositeSuite extends CardTestSuite { for (Map.Entry<EC_Curve, List<EC_Key>> curveKeys : mappedKeys.entrySet()) { EC_Curve curve = curveKeys.getKey(); List<Test> tests = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate)); - continue; - } - tests.add(allocate); - tests.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); + Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); String name; if (cfg.testOptions.contains("preset")) { @@ -50,13 +45,16 @@ public class CardCompositeSuite extends CardTestSuite { } else { name = "generated private key"; } - tests.add(setupKeypairs(curve, ExpectedValue.ANY, CardConsts.KEYPAIR_LOCAL)); + Test setKeypair = setupKeypairs(curve, ExpectedValue.ANY, CardConsts.KEYPAIR_LOCAL); + Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare keypair on " + curve.getId() + ".", allocate, set, setKeypair); + for (EC_Key key : curveKeys.getValue()) { Command ecdhCommand = new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.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."); tests.add(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with " + name + ", " + key.getDesc(), ecdh)); } - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", tests.toArray(new Test[0]))); + Test ecdhTest = CompoundTest.all(ExpectedValue.SUCCESS, "Do ECDH.", tests.toArray(new Test[0])); + doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", prepare, ecdhTest)); } diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java index 8390cd3..418ed2f 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java @@ -70,56 +70,40 @@ public class CardCompressionSuite extends CardTestSuite { String spec = keyLength + "b " + CardUtil.getKeyTypeString(field); byte curveId = EC_Consts.getCurve(keyLength, field); - Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), Result.ExpectedValue.SUCCESS)); - if (!allocateFirst.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for compression test on " + spec + ".", allocateFirst)); - continue; - } - List<Test> compressionTests = new LinkedList<>(); + Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), Result.ExpectedValue.SUCCESS); + Test setCustom = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curveId, domain, null), Result.ExpectedValue.SUCCESS); + Test genCustom = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), Result.ExpectedValue.SUCCESS); compressionTests.add(allocateFirst); - Test setCustom = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curveId, domain, null), Result.ExpectedValue.SUCCESS)); - Test genCustom = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), Result.ExpectedValue.SUCCESS)); compressionTests.add(setCustom); compressionTests.add(genCustom); - Response.Export key = new Command.Export(this.card, CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W).send(); - byte[] pubkey = key.getParameter(CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC); EC_Curve secgCurve = EC_Store.getInstance().getObject(EC_Curve.class, "secg", CardUtil.getCurveName(curveId)); - ECPoint pub; - try { - pub = ECUtil.fromX962(pubkey, secgCurve.toCurve()); - } catch (IllegalArgumentException iae) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "", compressionTests.toArray(new Test[0]))); - continue; - } + ECPoint pub = ECUtil.toPoint(ECUtil.fixedRandomPoint(secgCurve)); List<Test> kaTests = new LinkedList<>(); for (byte kaType : EC_Consts.KA_TYPES) { List<Test> thisTests = new LinkedList<>(); - 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, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), Result.ExpectedValue.SUCCESS)); + Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS); + Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), Result.ExpectedValue.SUCCESS); - thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement setup and basic test.", allocate, ka)); - if (ka.ok()) { - // tests of the good stuff - Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), Result.ExpectedValue.SUCCESS); - Test kaHybrid = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS_HYBRID, kaType), Result.ExpectedValue.SUCCESS); - thisTests.add(CompoundTest.any(Result.ExpectedValue.SUCCESS, "Tests of compressed and hybrid form.", kaCompressed, kaHybrid)); + thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement setup and basic test.", allocate, ka)); + // tests of the good stuff + Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), Result.ExpectedValue.SUCCESS); + Test kaHybrid = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS_HYBRID, kaType), Result.ExpectedValue.SUCCESS); + thisTests.add(CompoundTest.any(Result.ExpectedValue.SUCCESS, "Tests of compressed and hybrid form.", kaCompressed, kaHybrid)); - // tests the bad stuff here - byte[] pubHybrid = ECUtil.toX962Hybrid(pub, keyLength); - pubHybrid[pubHybrid.length - 1] ^= 1; - byte[] pubHybridEncoded = ByteUtil.prependLength(pubHybrid); - Test kaBadHybrid = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubHybridEncoded), Result.ExpectedValue.FAILURE); + // tests the bad stuff here + byte[] pubHybrid = ECUtil.toX962Hybrid(pub, keyLength); + pubHybrid[pubHybrid.length - 1] ^= 1; + byte[] pubHybridEncoded = ByteUtil.prependLength(pubHybrid); + Test kaBadHybrid = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubHybridEncoded), Result.ExpectedValue.FAILURE); - byte[] pubInfinityEncoded = {0x01, 0x00}; - Test kaBadInfinity = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubInfinityEncoded), Result.ExpectedValue.FAILURE); - thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of corrupted hybrid form and infinity.", kaBadHybrid, kaBadInfinity)); - } - kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement tests of " + CardUtil.getKATypeString(kaType) + ".", thisTests.toArray(new Test[0]))); - } + byte[] pubInfinityEncoded = {0x00}; + Test kaBadInfinity = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_INFINITY, kaType, pubInfinityEncoded), Result.ExpectedValue.FAILURE); + thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of corrupted hybrid form and infinity.", kaBadHybrid, kaBadInfinity)); + + kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement tests of " + CardUtil.getKATypeString(kaType) + ".", thisTests.toArray(new Test[0]))); } compressionTests.addAll(kaTests); if (cfg.cleanup) { @@ -137,12 +121,7 @@ public class CardCompressionSuite extends CardTestSuite { for (EC_Key.Public key : compressionKeys) { EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); List<Test> tests = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for non-residue test on " + curve.getBits() + "b " + curve.getId() + ".", allocate)); - continue; - } - tests.add(allocate); + tests.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); tests.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS)); tests.add(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS)); byte[] pointData = ECUtil.toX962Compressed(key.getParam(EC_Consts.PARAMETER_W)); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java index ebb1d3f..c365d52 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -13,7 +13,7 @@ import cz.crcs.ectester.reader.command.Command; import java.util.LinkedList; import java.util.List; -import java.util.Random; +import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -44,19 +44,13 @@ public class CardDefaultSuite extends CardTestSuite { short[] keySizes = field == EC_Consts.ALG_EC_FP ? EC_Consts.FP_SIZES : EC_Consts.F2M_SIZES; short domain = field == EC_Consts.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; for (short keyLength : keySizes) { - List<Test> supportTests = new LinkedList<>(); - Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS)); - if (!allocateFirst.ok()) { - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + keyLength + "b " + CardUtil.getKeyTypeString(field) + ".", allocateFirst)); - continue; - } + Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS); + Test genDefault = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS); + Test allocateSecond = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS); + Test setCustom = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.getCurve(keyLength, field), domain, null), ExpectedValue.SUCCESS); + Test genCustom = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS); supportTests.add(allocateFirst); - - Test genDefault = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); - Test allocateSecond = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS)); - Test setCustom = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.getCurve(keyLength, field), domain, null), ExpectedValue.SUCCESS)); - Test genCustom = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); supportTests.add(genDefault); supportTests.add(allocateSecond); supportTests.add(setCustom); @@ -64,68 +58,77 @@ public class CardDefaultSuite extends CardTestSuite { List<Test> kaTests = new LinkedList<>(); 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, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.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, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), ExpectedValue.SUCCESS)); + Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS); + Command ecdh = new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType); + Test ka = CommandTest.expect(ecdh, ExpectedValue.SUCCESS); + Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), ExpectedValue.SUCCESS); - String kaDesc = "Test of the " + CardUtil.getKATypeString(kaType) + " KeyAgreement."; - Function<Test[], Result> kaCallback = (tests) -> { - if (tests[1].ok() || tests[2].ok()) { - return new Result(Value.SUCCESS, "Some ECDH is supported."); + String kaDesc = "Test of the " + CardUtil.getKATypeString(kaType) + " KeyAgreement."; + Function<Test[], Result> kaCallback = (tests) -> { + if (tests[1].ok() || tests[2].ok()) { + return new Result(Value.SUCCESS, "Some ECDH is supported."); + } else { + return new Result(Value.FAILURE, "ECDH failed."); + } + }; + + Consumer<Test[]> runCallback = tests -> { + for (Test t : tests) { + if (t instanceof PerformanceTest) { + if (tests[0].ok() && tests[1].ok()) { + t.run(); + } } else { - return new Result(Value.FAILURE, "ECDH failed."); + t.run(); } - }; - - Test compound; - if (ka.ok()) { - Test perfTest = runTest(PerformanceTest.repeat(this.card, ecdh, 10)); - compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed, perfTest)); - } else { - compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed)); } + }; - kaTests.add(compound); - } else { - runTest(allocate); - kaTests.add(allocate); - } + Test perfTest = PerformanceTest.repeat(this.card, ecdh, 10); + Test compound = CompoundTest.function(kaCallback, runCallback, kaDesc, allocate, ka, kaCompressed, perfTest); + kaTests.add(compound); } - Test kaTest = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "KeyAgreement tests.", kaTests.toArray(new Test[0]))); + Test kaTest = CompoundTest.any(ExpectedValue.SUCCESS, "KeyAgreement tests.", kaTests.toArray(new Test[0])); supportTests.add(kaTest); List<Test> signTests = new LinkedList<>(); for (byte sigType : EC_Consts.SIG_TYPES) { - Test allocate = runTest(CommandTest.expect(new Command.AllocateSignature(this.card, sigType), ExpectedValue.SUCCESS)); - if (allocate.ok()) { - Command ecdsa = new Command.ECDSA(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_FALSE, null); - Test expect = runTest(CommandTest.expect(ecdsa, ExpectedValue.SUCCESS)); + Test allocate = CommandTest.expect(new Command.AllocateSignature(this.card, sigType), ExpectedValue.SUCCESS); + Command ecdsa = new Command.ECDSA(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_FALSE, null); + Test sign = CommandTest.expect(ecdsa, ExpectedValue.SUCCESS); - String signDesc = "Test of the " + CardUtil.getSigTypeString(sigType) + " signature."; + String signDesc = "Test of the " + CardUtil.getSigTypeString(sigType) + " signature."; - Random rand = new Random(); - byte[] sigData = new byte[64]; - rand.nextBytes(sigData); + byte[] sigData = new byte[]{(byte) domain, sigType}; - Test compound; - if (expect.ok()) { - Command ecdsaSign = new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_TRUE, sigData); - PerformanceTest signTest = runTest(PerformanceTest.repeat(this.card, "Sign", ecdsaSign, 10)); - byte[] signature = signTest.getResponses()[0].getParam(0); - Command ecdsaVerify = new Command.ECDSA_verify(this.card, CardConsts.KEYPAIR_LOCAL, sigType, sigData, signature); - PerformanceTest verifyTest = runTest(PerformanceTest.repeat(this.card, "Verify", ecdsaVerify, 10)); - compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect, signTest, verifyTest)); + Function<Test[], Result> sigCallback = (tests) -> { + if (tests[1].ok()) { + return new Result(Value.SUCCESS, "Some ECDSA is supported."); } else { - compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect)); + return new Result(Value.FAILURE, "ECDSA failed."); + } + }; + Consumer<Test[]> runCallback = tests -> { + for (Test t : tests) { + if (t instanceof PerformanceTest) { + if (tests[0].ok() && tests[1].ok()) { + t.run(); + } + } else { + t.run(); + } } - signTests.add(compound); - } else { - signTests.add(allocate); - } + }; + + Command ecdsaSign = new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_TRUE, sigData); + PerformanceTest signTest = PerformanceTest.repeat(this.card, "Sign", ecdsaSign, 10); + + CommandTestable.FunctionCommandTestable verifyTestable = new CommandTestable.FunctionCommandTestable(() -> new Command.ECDSA_verify(this.card, CardConsts.KEYPAIR_LOCAL, sigType, sigData, signTest.getResponses()[0].getParam(0))); + PerformanceTest verifyTest = PerformanceTest.repeat(this.card, "Verify", verifyTestable, 10); + Test compound = CompoundTest.function(sigCallback, runCallback, signDesc, allocate, sign, signTest, verifyTest); + signTests.add(compound); } - Test signTest = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Signature tests.", signTests.toArray(new Test[0]))); + Test signTest = CompoundTest.any(ExpectedValue.SUCCESS, "Signature tests.", signTests.toArray(new Test[0])); supportTests.add(signTest); 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()); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java index e2c07da..c731416 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java @@ -36,11 +36,7 @@ public class CardDegenerateSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List<EC_Key.Public> keys = e.getValue(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate)); - continue; - } + Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java index 0a82da3..fb24e30 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java @@ -143,15 +143,11 @@ public class CardEdgeCasesSuite extends CardTestSuite { 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, CardConsts.KEYPAIR_BOTH, curve.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "No support for " + curve.getBits() + "b " + curve.getId() + ".", key)); - continue; - } + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); CommandTest export = CommandTest.expect(new Command.Export(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), Result.ExpectedValue.SUCCESS); - Test setup = runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate, export)); + Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate, export); /* byte[] pParam = curve.getParam(EC_Consts.PARAMETER_FP)[0]; @@ -268,11 +264,7 @@ public class CardEdgeCasesSuite extends CardTestSuite { Arrays.sort(ps); Arrays.sort(zeros); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, secp160r1.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "No support for " + secp160r1.getBits() + "b secp160r1.", key)); - return; - } + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, secp160r1.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, secp160r1.getParams(), secp160r1.flatten()), Result.ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java index 4657de0..2fd457d 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java @@ -40,11 +40,7 @@ public class CardInvalidSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List<EC_Key.Public> keys = e.getValue(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate)); - continue; - } + Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), ExpectedValue.SUCCESS); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java index da4c0b5..3ffe07c 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.function.Function; /** * @author Jan Jancar johny@neuromancer.sk @@ -49,23 +50,36 @@ public class CardMiscSuite extends CardTestSuite { } private void testCurve(EC_Curve curve, String catName, Result.ExpectedValue expected) { - Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); - if (!allocateFirst.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst)); - return; - } - + Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); - Test generate = setupKeypairs(curve, Result.ExpectedValue.ANY, CardConsts.KEYPAIR_BOTH); + Test generate = setupKeypairs(curve, Result.ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH); Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), expected); Test sig = CommandTest.expect(new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, CardConsts.EXPORT_FALSE, null), expected); Test perform = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH and ECDSA.", ka, sig); + Function<Test[], Result> callback = (tests) -> { + if (!tests[0].ok()) { + return new Result(Result.Value.FAILURE, "Could not allocate keypairs."); + } + if (!tests[1].ok()) { + return new Result(Result.Value.FAILURE, "Could not set curve data."); + } + if (!tests[2].ok()) { + return new Result(Result.Value.FAILURE, "Could not generate keypairs."); + } + for (int i = 3; i < tests.length; i++) { + if (!tests[i].ok() && !(tests[i] instanceof CompoundTest)) { + return new Result(Result.Value.FAILURE, "ECDH or ECDSA did not work."); + } + } + return new Result(Result.Value.SUCCESS, "OK"); + }; + if (cfg.cleanup) { Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY); - doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform, cleanup)); + doTest(CompoundTest.function(callback, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform, cleanup)); } else { - doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform)); + doTest(CompoundTest.function(callback, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform)); } } 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 07b38d0..4c222cb 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 @@ -63,13 +63,7 @@ public class CardTestVectorSuite extends CardTestSuite { throw new IOException("Test vector keys couldn't be located."); } List<Test> testVector = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate)); - continue; - } - - testVector.add(allocate); + testVector.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.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, CardConsts.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); @@ -112,12 +106,7 @@ public class CardTestVectorSuite extends CardTestSuite { testCurves.addAll(EC_Store.getInstance().getObjects(EC_Curve.class, "brainpool").values().stream().filter((curve) -> curve.getField() == EC_Consts.ALG_EC_FP).collect(Collectors.toList())); for (EC_Curve curve : testCurves) { List<Test> testVector = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate)); - continue; - } - testVector.add(allocate); + testVector.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); CommandTest exportLocal = CommandTest.expect(new Command.Export(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), ExpectedValue.ANY); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java index 5c35be7..ea127e0 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java @@ -34,11 +34,7 @@ public class CardTwistSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List<EC_Key.Public> keys = e.getValue(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate)); - continue; - } + Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java index 0b030b8..605b2ec 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java @@ -42,24 +42,17 @@ public class CardWrongSuite extends CardTestSuite { for (Map.Entry<String, EC_Curve> e : curves.entrySet()) { EC_Curve curve = e.getValue(); List<Test> tests = new LinkedList<>(); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), key)); - continue; - } - tests.add(key); - Test set = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE)); - Test generate = runTest(setupKeypairs(curve, ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH)); - Test setup = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", set, generate)); + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); + Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE); + Test generate = setupKeypairs(curve, ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH); + Test setup = CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", key, set, generate); tests.add(setup); for (byte kaType : EC_Consts.KA_TYPES) { - Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS)); - if (allocate.ok()) { - Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), ExpectedValue.FAILURE)); - Test kaTest = runTest(CompoundTest.all(ExpectedValue.SUCCESS, "Allocate and perform KA.", allocate, ka)); - tests.add(kaTest); - } + Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS); + Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), ExpectedValue.FAILURE); + Test kaTest = CompoundTest.all(ExpectedValue.SUCCESS, "Allocate and perform KA.", allocate, ka); + tests.add(kaTest); } doTest(CompoundTest.function((tsts) -> { for (int i = 0; i < tsts.length; ++i) { @@ -82,11 +75,7 @@ public class CardWrongSuite extends CardTestSuite { Random r = new Random(); for (short keyLength : EC_Consts.FP_SIZES) { byte curve = EC_Consts.getCurve(keyLength, EC_Consts.ALG_EC_FP); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_FP), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_FP.", key)); - continue; - } + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_FP), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_FP, null), ExpectedValue.SUCCESS); Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); @@ -113,7 +102,7 @@ public class CardWrongSuite extends CardTestSuite { Test randomG = ecdhTest(new Command.Transform(this.card, CardConsts.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 fullRandomG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_FULLRANDOM), "Set G = random data.", "ECDH with G = random data."); - Test zeroG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = inifnity.", "ECDH with G = infinity."); + Test zeroG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = infinity.", "ECDH with G = infinity."); Test wrongG = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted G parameter.", randomG, fullRandomG, zeroG); byte[] originalR = EC_Consts.getCurveParameter(curve, EC_Consts.PARAMETER_R); @@ -162,11 +151,7 @@ public class CardWrongSuite extends CardTestSuite { */ for (short keyLength : EC_Consts.F2M_SIZES) { byte curve = EC_Consts.getCurve(keyLength, EC_Consts.ALG_EC_F2M); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_F2M), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_F2M.", key)); - continue; - } + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_F2M), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_F2M, null), ExpectedValue.SUCCESS); Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java index f670534..7733e11 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java @@ -6,13 +6,14 @@ import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import javax.smartcardio.CardException; +import java.util.function.Supplier; /** * @author Jan Jancar johny@neuromancer.sk */ public class CommandTestable extends BaseTestable { - private Command command; - private Response response; + protected Command command; + protected Response response; public CommandTestable(Command command) { this.command = command; @@ -41,4 +42,19 @@ public class CommandTestable extends BaseTestable { ok = true; } } + + public static class FunctionCommandTestable extends CommandTestable { + private Supplier<Command> supplier; + + public FunctionCommandTestable(Supplier<Command> supplier) { + super(null); + this.supplier = supplier; + } + + @Override + public void run() { + this.command = supplier.get(); + super.run(); + } + } } diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java b/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java index a725dc2..1171154 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java @@ -26,26 +26,38 @@ public class PerformanceTest extends SimpleTest<CommandTestable> { private int count; private String desc; + private PerformanceTest(CardMngr cardManager, CommandTestable testable, TestCallback<CommandTestable> callback, int count, String desc) { + super(testable, callback); + this.cardManager = cardManager; + this.count = count; + this.desc = desc; + } + private PerformanceTest(CardMngr cardManager, CommandTestable testable, int count, String desc) { - super(testable, new TestCallback<CommandTestable>() { + this(cardManager, testable, new TestCallback<CommandTestable>() { @Override public Result apply(CommandTestable testable) { return new Result(Result.Value.SUCCESS); } - }); - this.cardManager = cardManager; - this.count = count; - this.desc = desc; + }, count, desc); } public static PerformanceTest repeat(CardMngr cardManager, Command cmd, int count) { return new PerformanceTest(cardManager, new CommandTestable(cmd), count, null); } + public static PerformanceTest repeat(CardMngr cardManager, CommandTestable testable, int count) { + return new PerformanceTest(cardManager, testable, count, null); + } + public static PerformanceTest repeat(CardMngr cardManager, String desc, Command cmd, int count) { return new PerformanceTest(cardManager, new CommandTestable(cmd), count, desc); } + public static PerformanceTest repeat(CardMngr cardManager, String desc, CommandTestable testable, int count) { + return new PerformanceTest(cardManager, testable, count, desc); + } + @Override public String getDescription() { String rest = String.format("Mean = %d ns, Median = %d ns, Mode = %d ns", mean, median, mode); diff --git a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java new file mode 100644 index 0000000..173f7e2 --- /dev/null +++ b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java @@ -0,0 +1,141 @@ +package cz.crcs.ectester.reader; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.StdIo; +import org.junitpioneer.jupiter.StdOut; + +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class AppTests { + + @Test + @StdIo() + public void help(StdOut out) { + ECTesterReader.main(new String[]{"-h"}); + String s = out.capturedString(); + assertTrue(s.contains("ECTesterReader")); + } + + @Test + @StdIo() + public void listSuites(StdOut out) { + ECTesterReader.main(new String[]{"--list-suites"}); + String s = out.capturedString(); + assertTrue(s.contains("default test suite")); + } + + @Test + @StdIo() + public void listData(StdOut out) { + ECTesterReader.main(new String[]{"--list-named"}); + String s = out.capturedString(); + 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() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "default", "-s"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + @Disabled + public void testVectorSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "test-vectors", "-s"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + public void compressionSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "compression", "-s"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + @Disabled + public void wrongSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "wrong", "-s", "-y"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + public void degenerateSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "degenerate", "-s", "-y"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + @Disabled + public void cofactorSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "cofactor", "-s", "-y"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + @Disabled + public void compositeSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "composite", "-s", "-y"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + public void invalidSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "invalid", "-s", "-y"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + public void edgeCasesSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "edge-cases", "-s", "-y"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + public void signatureSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "signature", "-s"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + public void twistSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "twist", "-s", "-y"})); + } + + @Test + @XFail(value = "JCardSim sometimes times-out.") + public void miscellaneousSuite() { + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "miscellaneous", "-s", "-y"})); + } + + @Test + public void generate() { + ECTesterReader.main(new String[]{"-g", "10", "-s", "-fp", "-o", "/dev/null", "-b", "256"}); + } + + @Test + public void ecdh() { + ECTesterReader.main(new String[]{"-dh", "-fp", "-b", "256", "-s"}); + } + + @Test + public void ecdsa() { + ECTesterReader.main(new String[]{"-dsa", "-fp", "-b", "256", "-s"}); + } + + @Test + public void export() { + ECTesterReader.main(new String[]{"-e", "-fp", "-b", "256", "-s", "-o", "/dev/null"}); + } + + @Test + public void info() { + ECTesterReader.main(new String[]{"-nf", "-s"}); + } +} diff --git a/reader/src/test/java/cz/crcs/ectester/reader/XFail.java b/reader/src/test/java/cz/crcs/ectester/reader/XFail.java new file mode 100644 index 0000000..f42f530 --- /dev/null +++ b/reader/src/test/java/cz/crcs/ectester/reader/XFail.java @@ -0,0 +1,86 @@ +/* + * Copyright 2016-2023 the original author or authors. + * Taken from https://github.com/junit-pioneer/junit-pioneer/blob/98cef28462c8b7ab66231cc5b7e8daef3b329f67/src/main/java/org/junitpioneer/jupiter/ExpectedToFail.java + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package cz.crcs.ectester.reader; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import org.junit.jupiter.api.extension.ExtendWith; + +/** + * {@code @ExpectedToFail} is a JUnit Jupiter extension to mark test methods as temporarily + * 'expected to fail'. Such test methods will still be executed but when they result in a test + * failure or error the test will be aborted. However, if the test method unexpectedly executes + * successfully, it is marked as failure to let the developer know that the test is now + * successful and that the {@code @ExpectedToFail} annotation can be removed. + * + * <p>The big difference compared to JUnit's {@link org.junit.jupiter.api.Disabled @Disabled} + * annotation is that the developer is informed as soon as a test is successful again. + * This helps to avoid creating duplicate tests by accident and counteracts the accumulation + * of disabled tests over time.</p> + * + * <p>Further, the {@link #withExceptions()} attribute can be used to restrict the extension's behavior + * to specific exceptions. That is, only if the test method ends up throwing one of the specified exceptions + * will the test be aborted. This can, for example, be used when the production code temporarily throws + * an {@link UnsupportedOperationException} because some feature has not been implemented yet, but the + * test method is already implemented and should not fail on a failing assertion. + * </p> + * + * <p>The annotation can only be used on methods and as meta-annotation on other annotation types. + * Similar to {@code @Disabled}, it has to be used in addition to a "testable" annotation, such + * as {@link org.junit.jupiter.api.Test @Test}. Otherwise the annotation has no effect.</p> + * + * <p><b>Important:</b> This annotation is <b>not</b> intended as a way to mark test methods + * which intentionally cause exceptions. Such test methods should use + * {@link org.junit.jupiter.api.Assertions#assertThrows(Class, org.junit.jupiter.api.function.Executable) assertThrows} + * or similar means to explicitly test for a specific exception class being thrown by a + * specific action.</p> + * + * <p>For more details and examples, see + * <a href="https://junit-pioneer.org/docs/expected-to-fail-tests/" target="_top">the documentation on <code>@ExpectedToFail</code></a>.</p> + * + * @since 1.8.0 + * @see org.junit.jupiter.api.Disabled + */ +@Documented +@Retention(RUNTIME) +/* + * Only supports METHOD and ANNOTATION_TYPE as targets but not test classes because there + * it is not clear what the 'correct' behavior would be when only a few test methods + * execute successfully. Would the developer then have to remove the @ExpectedToFail annotation + * from the test class and annotate methods individually? + */ +@Target({ METHOD, ANNOTATION_TYPE }) +@ExtendWith(XFailExtension.class) +public @interface XFail { + + /** + * Defines the message to show when a test is aborted because it is failing. + * This can be used for example to briefly explain why the tested code is not working + * as intended at the moment. + * An empty string (the default) causes a generic default message to be used. + */ + String value() default ""; + + /** + * Specifies which exceptions are expected to be thrown and will cause the test to be aborted rather than fail. + * An empty array is considered a configuration error and will cause the test to fail. Instead, consider leaving + * the attribute set to the default value when any exception should cause the test to be aborted. + */ + Class<? extends Throwable>[] withExceptions() default { Throwable.class }; + +}
\ No newline at end of file diff --git a/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java b/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java new file mode 100644 index 0000000..b190e1a --- /dev/null +++ b/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java @@ -0,0 +1,86 @@ +/* + * Copyright 2016-2023 the original author or authors. + * Taken from https://github.com/junit-pioneer/junit-pioneer/blob/98cef28462c8b7ab66231cc5b7e8daef3b329f67/src/main/java/org/junitpioneer/jupiter/ExpectedToFailExtension.java + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package cz.crcs.ectester.reader; + +import java.lang.reflect.Method; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionConfigurationException; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.InvocationInterceptor; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; +import org.junit.platform.commons.support.AnnotationSupport; +import org.opentest4j.AssertionFailedError; +import org.opentest4j.TestAbortedException; + +class XFailExtension implements Extension, InvocationInterceptor { + + @Override + public void interceptTestMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, + ExtensionContext extensionContext) throws Throwable { + invokeAndInvertResult(invocation, extensionContext); + } + + private static void invokeAndInvertResult(Invocation<Void> invocation, ExtensionContext extensionContext) + throws Throwable { + XFail expectedToFail = getExpectedToFailAnnotation(extensionContext); + if (expectedToFail.withExceptions().length == 0) { + throw new ExtensionConfigurationException("@XFail withExceptions must not be empty"); + } + + try { + invocation.proceed(); + // at this point, the invocation succeeded, so we'd want to call `fail(...)`, + // but that would get handled by the following `catch` and so it's easier + // to instead fall through to a `fail(...)` after the `catch` block + } + catch (Throwable t) { + if (shouldPreserveException(t)) { + throw t; + } + + if (Stream.of(expectedToFail.withExceptions()).noneMatch(clazz -> clazz.isInstance(t))) { + throw new AssertionFailedError( + "Test marked as temporarily 'expected to fail' failed with an unexpected exception", t); + } + + String message = expectedToFail.value(); + if (message.isEmpty()) { + message = "Test marked as temporarily 'expected to fail' failed as expected"; + } + + throw new TestAbortedException(message, t); + } + } + + /** + * Returns whether the exception should be preserved and reported as is instead + * of considering it an 'expected to fail' exception. + * + * <p>This method is used for exceptions that abort test execution and should + * have higher precedence than aborted exceptions thrown by this extension.</p> + */ + private static boolean shouldPreserveException(Throwable t) { + // Note: Ideally would use the same logic JUnit uses to determine if exception is aborting + // execution, see its class OpenTest4JAndJUnit4AwareThrowableCollector + return t instanceof TestAbortedException; + } + + private static XFail getExpectedToFailAnnotation(ExtensionContext context) { + return AnnotationSupport + .findAnnotation(context.getRequiredTestMethod(), XFail.class) + .orElseThrow(() -> new IllegalStateException("@XFail is missing.")); + + } + +}
\ No newline at end of file |
