From 395d5fbce19e974c1621b7906c674428f8da5bd4 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 24 Sep 2017 16:30:18 +0200 Subject: Add class docs to EC_* classes. --- src/cz/crcs/ectester/reader/Command.java | 10 ++++++++++ src/cz/crcs/ectester/reader/ec/EC_Category.java | 2 ++ src/cz/crcs/ectester/reader/ec/EC_Curve.java | 2 ++ src/cz/crcs/ectester/reader/ec/EC_Data.java | 4 ++++ src/cz/crcs/ectester/reader/ec/EC_KAResult.java | 2 ++ src/cz/crcs/ectester/reader/ec/EC_Key.java | 8 ++++++++ src/cz/crcs/ectester/reader/ec/EC_Keypair.java | 2 ++ src/cz/crcs/ectester/reader/ec/EC_Params.java | 5 +++++ 8 files changed, 35 insertions(+) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java index 8cb3a30..cf05972 100644 --- a/src/cz/crcs/ectester/reader/Command.java +++ b/src/cz/crcs/ectester/reader/Command.java @@ -466,6 +466,16 @@ public abstract class Command { private byte type; private byte[] pubkey; + /** + * 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 corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) + * @param type ECDH algorithm type (EC_Consts.KA_* | ...) + * @param pubkey pubkey data to do ECDH with. + */ protected ECDH_direct(CardMngr cardManager, byte privkey, byte export, short corruption, byte type, byte[] pubkey) { super(cardManager); this.privkey = privkey; diff --git a/src/cz/crcs/ectester/reader/ec/EC_Category.java b/src/cz/crcs/ectester/reader/ec/EC_Category.java index 97dd1b4..41cbad8 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Category.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Category.java @@ -6,6 +6,8 @@ import java.util.Objects; import java.util.TreeMap; /** + * A category of EC_Data objects, has a name, description and represents a directory in + * the cz.crcs.ectester.data package. * @author Jan Jancar johny@neuromancer.sk */ public class EC_Category { diff --git a/src/cz/crcs/ectester/reader/ec/EC_Curve.java b/src/cz/crcs/ectester/reader/ec/EC_Curve.java index 45080fb..cb4a2df 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Curve.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Curve.java @@ -4,6 +4,8 @@ import cz.crcs.ectester.applet.EC_Consts; import javacard.security.KeyPair; /** + * An Elliptic curve, contains parameters Fp/F2M, A, B, G, R, (K)?. + * * @author Jan Jancar johny@neuromancer.sk */ public class EC_Curve extends EC_Params { diff --git a/src/cz/crcs/ectester/reader/ec/EC_Data.java b/src/cz/crcs/ectester/reader/ec/EC_Data.java index 9dcbbe0..0ceddef 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Data.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Data.java @@ -7,6 +7,10 @@ import java.util.*; import java.util.regex.Pattern; /** + * A list of byte arrays for holding EC data. + * + * The data can be read from a byte array via readBytes(), from a CSV via readCSV(). + * The data can be exported to a byte array via flatten() or to a string array via expand(). * @author Jan Jancar johny@neuromancer.sk */ public abstract class EC_Data { diff --git a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java b/src/cz/crcs/ectester/reader/ec/EC_KAResult.java index 28115f7..4a67bbe 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java +++ b/src/cz/crcs/ectester/reader/ec/EC_KAResult.java @@ -3,6 +3,8 @@ package cz.crcs.ectester.reader.ec; import cz.crcs.ectester.reader.Util; /** + * A result of EC based Key agreement operation. + * * @author Jan Jancar johny@neuromancer.sk */ public class EC_KAResult extends EC_Data { diff --git a/src/cz/crcs/ectester/reader/ec/EC_Key.java b/src/cz/crcs/ectester/reader/ec/EC_Key.java index cecd228..e1adcf1 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Key.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Key.java @@ -3,6 +3,8 @@ package cz.crcs.ectester.reader.ec; import cz.crcs.ectester.applet.EC_Consts; /** + * An abstract-like EC key. Concrete implementations create a public and private keys. + * * @author Jan Jancar johny@neuromancer.sk */ public class EC_Key extends EC_Params { @@ -38,6 +40,9 @@ public class EC_Key extends EC_Params { return desc; } + /** + * An EC public key, contains the W parameter. + */ public static class Public extends EC_Key { public Public(String curve) { @@ -54,6 +59,9 @@ public class EC_Key extends EC_Params { } } + /** + * An EC private key, contains the S parameter. + */ public static class Private extends EC_Key { public Private(String curve) { diff --git a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java b/src/cz/crcs/ectester/reader/ec/EC_Keypair.java index 924906e..e7da027 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Keypair.java @@ -3,6 +3,8 @@ package cz.crcs.ectester.reader.ec; import cz.crcs.ectester.applet.EC_Consts; /** + * An EC keypair, contains both the W and S parameters. + * * @author Jan Jancar johny@neuromancer.sk */ public class EC_Keypair extends EC_Params { diff --git a/src/cz/crcs/ectester/reader/ec/EC_Params.java b/src/cz/crcs/ectester/reader/ec/EC_Params.java index ea2e633..6fb164b 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Params.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Params.java @@ -8,6 +8,11 @@ import java.util.ArrayList; import java.util.List; /** + * A list of EC parameters, can contain a subset of the Fp/F2M, A, B, G, R, K, W, S parameters. + * + * The set of parameters is uniquely identified by a short bit string. + * The parameters can be exported to a byte array via flatten() or to a comma delimited + * string via expand(). * @author Jan Jancar johny@neuromancer.sk */ public class EC_Params extends EC_Data { -- cgit v1.2.3-70-g09d2 From dcce315f38127f82ff43b580fc6e25345adbe6e3 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 30 Sep 2017 18:05:20 +0200 Subject: Rename nonprime curves to -> composite curves. --- TESTS.md | 8 ++-- src/cz/crcs/ectester/data/categories.xml | 6 +-- .../crcs/ectester/data/composite/composite128.csv | 1 + .../ectester/data/composite/composite128_pub.csv | 1 + .../crcs/ectester/data/composite/composite160.csv | 1 + .../ectester/data/composite/composite160_pub.csv | 1 + .../crcs/ectester/data/composite/composite192.csv | 1 + .../ectester/data/composite/composite192_pub.csv | 1 + .../crcs/ectester/data/composite/composite224.csv | 1 + .../ectester/data/composite/composite224_pub.csv | 1 + .../crcs/ectester/data/composite/composite256.csv | 1 + .../ectester/data/composite/composite256_pub.csv | 1 + .../crcs/ectester/data/composite/composite384.csv | 1 + .../ectester/data/composite/composite384_pub.csv | 1 + .../crcs/ectester/data/composite/composite521.csv | 1 + .../ectester/data/composite/composite521_pub.csv | 1 + src/cz/crcs/ectester/data/composite/curves.xml | 46 +++++++++++++++++++++ src/cz/crcs/ectester/data/composite/keys.xml | 48 ++++++++++++++++++++++ src/cz/crcs/ectester/data/nonprime/curves.xml | 46 --------------------- src/cz/crcs/ectester/data/nonprime/keys.xml | 48 ---------------------- src/cz/crcs/ectester/data/nonprime/nonprime128.csv | 1 - .../ectester/data/nonprime/nonprime128_pub.csv | 1 - src/cz/crcs/ectester/data/nonprime/nonprime160.csv | 1 - .../ectester/data/nonprime/nonprime160_pub.csv | 1 - src/cz/crcs/ectester/data/nonprime/nonprime192.csv | 1 - .../ectester/data/nonprime/nonprime192_pub.csv | 1 - src/cz/crcs/ectester/data/nonprime/nonprime224.csv | 1 - .../ectester/data/nonprime/nonprime224_pub.csv | 1 - src/cz/crcs/ectester/data/nonprime/nonprime256.csv | 1 - .../ectester/data/nonprime/nonprime256_pub.csv | 1 - src/cz/crcs/ectester/data/nonprime/nonprime384.csv | 1 - .../ectester/data/nonprime/nonprime384_pub.csv | 1 - src/cz/crcs/ectester/data/nonprime/nonprime521.csv | 1 - .../ectester/data/nonprime/nonprime521_pub.csv | 1 - src/cz/crcs/ectester/reader/ECTester.java | 8 ++-- src/cz/crcs/ectester/reader/TestSuite.java | 10 ++--- 36 files changed, 124 insertions(+), 124 deletions(-) create mode 100644 src/cz/crcs/ectester/data/composite/composite128.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite128_pub.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite160.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite160_pub.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite192.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite192_pub.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite224.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite224_pub.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite256.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite256_pub.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite384.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite384_pub.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite521.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite521_pub.csv create mode 100644 src/cz/crcs/ectester/data/composite/curves.xml create mode 100644 src/cz/crcs/ectester/data/composite/keys.xml delete mode 100644 src/cz/crcs/ectester/data/nonprime/curves.xml delete mode 100644 src/cz/crcs/ectester/data/nonprime/keys.xml delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime128.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime128_pub.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime160.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime160_pub.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime192.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime192_pub.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime224.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime224_pub.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime256.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime256_pub.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime384.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime384_pub.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime521.csv delete mode 100644 src/cz/crcs/ectester/data/nonprime/nonprime521_pub.csv (limited to 'src') diff --git a/TESTS.md b/TESTS.md index 465ca5d..21298dc 100644 --- a/TESTS.md +++ b/TESTS.md @@ -3,10 +3,10 @@ - `default` - `test-vectors` - `wrong` - - `nonprime` + - `composite` - `invalid` -**NOTE: The `wrong`, `nonprime` and `invalid` test suites caused temporary DoS of some cards. These test suites prompt you for +**NOTE: The `wrong`, `composite` and `invalid` test suites caused temporary DoS of some cards. These test suites prompt you for confirmation before running, be cautious.** ## Default @@ -68,14 +68,14 @@ java -jar ECTester.jar -t wrong -b 521 -fp ``` tests a 521 bit(`-b`), prime-field(`-fp`) wrong curve. -## Nonprime +## Composite Tests using curves that don't have a prime order/nearly prime order. These tests should generally fail, a success here implies the card **WILL** use a non-secure curve if such curve is set by the applet. Operations over such curves are susceptible to small-subgroup attacks. For example: ```bash -java -jar ECTester.jar -t nonprime -b 160 -fp +java -jar ECTester.jar -t composite -b 160 -fp ``` ## Invalid diff --git a/src/cz/crcs/ectester/data/categories.xml b/src/cz/crcs/ectester/data/categories.xml index c53a7c0..750fa8c 100644 --- a/src/cz/crcs/ectester/data/categories.xml +++ b/src/cz/crcs/ectester/data/categories.xml @@ -32,9 +32,9 @@ GOST R 34.10-2001: RFC5832 - nonprime - nonprime - Non-prime order curves, with points of very small order pregenerated. + composite + composite + Composite order curves, with points of very small order pregenerated. wrong diff --git a/src/cz/crcs/ectester/data/composite/composite128.csv b/src/cz/crcs/ectester/data/composite/composite128.csv new file mode 100644 index 0000000..b666e20 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite128.csv @@ -0,0 +1 @@ +0xcfba21fd0483b1f300fa2506a5a566ef,0x36d9a5acac27a008e36cbe3e9f103fde,0xa67cf5fa09fb1db902068c87046ae21e,0x47d78391a4b9fff6a0db1292f9cd0e6a,0x9aed9c92f8bb3dbd42402165a270bd6f,0xcfba21fd0483b1f333d61a5af6ada2c7,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite128_pub.csv b/src/cz/crcs/ectester/data/composite/composite128_pub.csv new file mode 100644 index 0000000..a1fbe5c --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite128_pub.csv @@ -0,0 +1 @@ +0x63901e122761d9c16565b2f38e991f71,0xb9d99fbc3154a96ca23ecff770cbbe4f \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite160.csv b/src/cz/crcs/ectester/data/composite/composite160.csv new file mode 100644 index 0000000..e685a11 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite160.csv @@ -0,0 +1 @@ +0xdc13490ff9857b111f44c0500770a6457e683223,0xa3ecd7d51e79d72d2700184c795aa8a6b8e66573,0x8ac43592905f995cb13f3694317bf470adafb645,0x5f8e88afc117c722859fe8e55647bca69ba82150,0x93e6dcaee271e9f2838c98b7d06eccc5d7c800e5,0xdc13490ff9857b111f446ef4a6d1e1715f6a6dff,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite160_pub.csv b/src/cz/crcs/ectester/data/composite/composite160_pub.csv new file mode 100644 index 0000000..7060146 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite160_pub.csv @@ -0,0 +1 @@ +0x59c9c3c8aef29f1c1c500cafb4726da6086e6eb0,0xd695a76005eddb26afd40ee20904778bb3497bb1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite192.csv b/src/cz/crcs/ectester/data/composite/composite192.csv new file mode 100644 index 0000000..c61f65c --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite192.csv @@ -0,0 +1 @@ +0xce714cc3a15ce7e5dab068c9a1f8be00aad480abccaeefc3,0x597c781f64c33eb8ef919c415911518ea323be88b9437caf,0xf81585a1b18f233d70add7ee1342d2035c386a92e3ab8320,0x150ff0a40deac6462b5987418617fdeeb6bfd76d4d60a067,0x843d577371c5dce122c2ff206b2f42fa0b842b49bdaf990f,0xce714cc3a15ce7e5dab068c9a30bc92915bd8662ae882887,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite192_pub.csv b/src/cz/crcs/ectester/data/composite/composite192_pub.csv new file mode 100644 index 0000000..97c66cd --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite192_pub.csv @@ -0,0 +1 @@ +0x17047f91dbe33032c9d09bd29ceadd8a09ccc32ac6309541,0x6a726de54fbd59cfc352e838b337fa005a97180816135e6a \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite224.csv b/src/cz/crcs/ectester/data/composite/composite224.csv new file mode 100644 index 0000000..cd4c5f8 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite224.csv @@ -0,0 +1 @@ +0xeed4c3d98f1c9b9518f116263db770366877d12df6a9cf08b96dd4bb,0x8d4dddb0317d6a6bf9a4dbbed3a43fa21f79869c5ab9729d239e9282,0x46873614be3dffc9218082322210c0616140286f2d160503c1a9250d,0x961bbb1fc9955a71c91a50aedcd2f14fccb660af992b0030b9c90b36,0x1c00f6d0bd405dd7d3016fb8c0c75e4ecec70fe61237f6d24008a5fd,0xeed4c3d98f1c9b9518f116263db821c36a06adae17162ad3162f68c3,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite224_pub.csv b/src/cz/crcs/ectester/data/composite/composite224_pub.csv new file mode 100644 index 0000000..aa2ab06 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite224_pub.csv @@ -0,0 +1 @@ +0xcfd92aea0f79190c48ca703eb8a9baa7099a23bb39578261fe4d0f04,0x257a3d98de44bd25404977a4ac7fc56d3d4e827f085b7cf5247524c4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256.csv b/src/cz/crcs/ectester/data/composite/composite256.csv new file mode 100644 index 0000000..582b115 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite256.csv @@ -0,0 +1 @@ +0xc9a803b1eaf849f1c02cfd1dbfac68623985c88b37103b338ae11d2597ee8445,0x4841c5775a24a884ca36ec362b44645a2f60b25d002c4fc1d9f139870fe0cc71,0x1b097456751f3534190dae568f80a2c6ff55dddfe072a7dc6467a4b6476b6880,0xa1fd34a27afb1340b8e4a7db2a5ec5a1432c6dc8555af9f78fca2cf740cab2b7,0x98419c698cab6c7dbb53eb2751417b52ccded4680c5e09543f93c7886c3a173e,0xc9a803b1eaf849f1c02cfd1dbfac6863128c5b1fc5acd5b5e0fc0a7311fb5b1d,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_pub.csv b/src/cz/crcs/ectester/data/composite/composite256_pub.csv new file mode 100644 index 0000000..60f475c --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite256_pub.csv @@ -0,0 +1 @@ +0x75fce70968862d53e29548aad70582514e960d8128bd3c5f8c4dbe2cf8dad653,0x55aa4b7d3882fb0a83bd00c9c3bae17f1024d64aec67e1db38ef671e6350beae \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite384.csv b/src/cz/crcs/ectester/data/composite/composite384.csv new file mode 100644 index 0000000..ffcbe91 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite384.csv @@ -0,0 +1 @@ +0xd0df6c96cff7081be80d22b005758a2e2f046e15fe020ef886e21b492ac57257a923144bcad989ab6341bd3b700f914b,0x45c64503be019afd3462b361ad2b2a3bca0aeccc5494a624fb632455e62b4f0c98f944fa97c37811da039823cd77c906,0xd85583f7f11ad23ec75ed5a414153a06d6640936b8103f5df691fa95cf2afa78f3ea5addc225b144964048c9f7592ae4,0x2b1341d12dff4f9cf9427c4752962b4c2bdc8fbcd80652516c421cc523212a01ea63c79d6e9a9c84933e353e212416ec,0xce416c6e75fa9fd205ed48fc4e3099cbb1d6ed031b7ddbff1d634eb97a83d9b780cfd4dedfdd2c7604d143196c08d933,0xd0df6c96cff7081be80d22b005758a2e2f046e15fe020ef7664ed51d7701c86bf2a1e9f3002c26fe002314c3c92f1ca9,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite384_pub.csv b/src/cz/crcs/ectester/data/composite/composite384_pub.csv new file mode 100644 index 0000000..236602e --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite384_pub.csv @@ -0,0 +1 @@ +0xa4bd575bf20300b0cf8a2f41dd5a03e908966a4229a5f22f5c190d3641ac2d32b7b24a63482cbbcd0c2257f834834ef1,0x38d51c8f9e90592f567e81d0e4855e79731b5797857a4c7dc270653bc9f0c31e84693007b09cebf710d5ae3237303949 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite521.csv b/src/cz/crcs/ectester/data/composite/composite521.csv new file mode 100644 index 0000000..b65c980 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite521.csv @@ -0,0 +1 @@ +0x01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc79cf188d9ee82d1a51c44cbd31e9cc5b816d76d5b1312b005f7b68919e275dac99f,0x00401639f36f2ee45fc164ea3e1f14f4803fd7a77ffdfb392c3f8fe95d1aea331467f4618d59aeee49d5d7c70caf320f7dd1ac166114f562413449991d3aa1a2c49e,0x004a26a8c47fce204ba953015fa86708c0de720f27523988b097e774168c15f7a215aaf18a5f1b9579ab3db935d45be14c9a87b71170396909b14d06f7a09975b3a6,0x01c880ae0a355a52791fc9600fd8b35726e9d799101489161c8f90a9c6631d09b3cb347584837d9deb8566a9c5846aded0d01eb947b4affd34e8ea7dbe733cbedafa,0x00050f12672f163f19d5d493eb82ef777b0213dd4e0cf75a9b99724fbdb54b0cc4e037bf86a48bac28467bdd936c314ce13f6ec7ec69ea09ae4f5444df4b2a117a66,0x01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc7ba0838717c1947f93cfdd3ed87ec2c2df181c7ada553346ec1495732a1e7ffe9b3,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite521_pub.csv b/src/cz/crcs/ectester/data/composite/composite521_pub.csv new file mode 100644 index 0000000..9695924 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite521_pub.csv @@ -0,0 +1 @@ +0x002844df0f31f46a40e6c7006cde99155bd5d18d0e4150178a8e307d6aec08fd02d466c03c49b49c2654b7c9a32d88ca014016a7eddd44217be915505d228efb9389,0x0105921e2172c3050ba4c9d2e744fc5b7b5e8451751e6780c6de88229497be7d23550beefa0cb7fafebb4dd9fad1244c6733befe5a97710f0dc56dc08d9d9df9d846 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/curves.xml b/src/cz/crcs/ectester/data/composite/curves.xml new file mode 100644 index 0000000..e940efe --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/curves.xml @@ -0,0 +1,46 @@ + + + + composite128 + 128 + prime + composite128.csv + + + composite160 + 160 + prime + composite160.csv + + + composite192 + 192 + prime + composite192.csv + + + composite224 + 224 + prime + composite224.csv + + + composite256 + 256 + prime + composite256.csv + + + composite384 + 384 + prime + composite384.csv + + + composite521 + 521 + prime + composite521.csv + + \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/keys.xml b/src/cz/crcs/ectester/data/composite/keys.xml new file mode 100644 index 0000000..2835615 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/keys.xml @@ -0,0 +1,48 @@ + + + + composite128-pub + composite128_pub.csv + composite/composite128 + order = 5 + + + composite160-pub + composite160_pub.csv + composite/composite160 + order = 3 + + + composite192-pub + composite192_pub.csv + composite/composite192 + order = 3 + + + composite224-pub + composite224_pub.csv + composite/composite224 + order = 5 + + + composite256-pub + composite256_pub.csv + composite/composite256 + order = 3 + + + composite384-pub + composite384_pub.csv + composite/composite384 + order = 3 + + + composite521-pub + composite521_pub.csv + composite/composite521 + order = 5 + + \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/curves.xml b/src/cz/crcs/ectester/data/nonprime/curves.xml deleted file mode 100644 index e0eb78a..0000000 --- a/src/cz/crcs/ectester/data/nonprime/curves.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - nonprime128 - 128 - prime - nonprime128.csv - - - nonprime160 - 160 - prime - nonprime160.csv - - - nonprime192 - 192 - prime - nonprime192.csv - - - nonprime224 - 224 - prime - nonprime224.csv - - - nonprime256 - 256 - prime - nonprime256.csv - - - nonprime384 - 384 - prime - nonprime384.csv - - - nonprime521 - 521 - prime - nonprime521.csv - - \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/keys.xml b/src/cz/crcs/ectester/data/nonprime/keys.xml deleted file mode 100644 index c10ae65..0000000 --- a/src/cz/crcs/ectester/data/nonprime/keys.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - nonprime128-pub - nonprime128_pub.csv - nonprime/nonprime128 - order = 5 - - - nonprime160-pub - nonprime160_pub.csv - nonprime/nonprime160 - order = 3 - - - nonprime192-pub - nonprime192_pub.csv - nonprime/nonprime192 - order = 3 - - - nonprime224-pub - nonprime224_pub.csv - nonprime/nonprime224 - order = 5 - - - nonprime256-pub - nonprime256_pub.csv - nonprime/nonprime256 - order = 3 - - - nonprime384-pub - nonprime384_pub.csv - nonprime/nonprime384 - order = 3 - - - nonprime521-pub - nonprime521_pub.csv - nonprime/nonprime521 - order = 5 - - \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime128.csv b/src/cz/crcs/ectester/data/nonprime/nonprime128.csv deleted file mode 100644 index b666e20..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime128.csv +++ /dev/null @@ -1 +0,0 @@ -0xcfba21fd0483b1f300fa2506a5a566ef,0x36d9a5acac27a008e36cbe3e9f103fde,0xa67cf5fa09fb1db902068c87046ae21e,0x47d78391a4b9fff6a0db1292f9cd0e6a,0x9aed9c92f8bb3dbd42402165a270bd6f,0xcfba21fd0483b1f333d61a5af6ada2c7,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime128_pub.csv b/src/cz/crcs/ectester/data/nonprime/nonprime128_pub.csv deleted file mode 100644 index a1fbe5c..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime128_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x63901e122761d9c16565b2f38e991f71,0xb9d99fbc3154a96ca23ecff770cbbe4f \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime160.csv b/src/cz/crcs/ectester/data/nonprime/nonprime160.csv deleted file mode 100644 index e685a11..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime160.csv +++ /dev/null @@ -1 +0,0 @@ -0xdc13490ff9857b111f44c0500770a6457e683223,0xa3ecd7d51e79d72d2700184c795aa8a6b8e66573,0x8ac43592905f995cb13f3694317bf470adafb645,0x5f8e88afc117c722859fe8e55647bca69ba82150,0x93e6dcaee271e9f2838c98b7d06eccc5d7c800e5,0xdc13490ff9857b111f446ef4a6d1e1715f6a6dff,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime160_pub.csv b/src/cz/crcs/ectester/data/nonprime/nonprime160_pub.csv deleted file mode 100644 index 7060146..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime160_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x59c9c3c8aef29f1c1c500cafb4726da6086e6eb0,0xd695a76005eddb26afd40ee20904778bb3497bb1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime192.csv b/src/cz/crcs/ectester/data/nonprime/nonprime192.csv deleted file mode 100644 index c61f65c..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime192.csv +++ /dev/null @@ -1 +0,0 @@ -0xce714cc3a15ce7e5dab068c9a1f8be00aad480abccaeefc3,0x597c781f64c33eb8ef919c415911518ea323be88b9437caf,0xf81585a1b18f233d70add7ee1342d2035c386a92e3ab8320,0x150ff0a40deac6462b5987418617fdeeb6bfd76d4d60a067,0x843d577371c5dce122c2ff206b2f42fa0b842b49bdaf990f,0xce714cc3a15ce7e5dab068c9a30bc92915bd8662ae882887,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime192_pub.csv b/src/cz/crcs/ectester/data/nonprime/nonprime192_pub.csv deleted file mode 100644 index 97c66cd..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime192_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x17047f91dbe33032c9d09bd29ceadd8a09ccc32ac6309541,0x6a726de54fbd59cfc352e838b337fa005a97180816135e6a \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime224.csv b/src/cz/crcs/ectester/data/nonprime/nonprime224.csv deleted file mode 100644 index cd4c5f8..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime224.csv +++ /dev/null @@ -1 +0,0 @@ -0xeed4c3d98f1c9b9518f116263db770366877d12df6a9cf08b96dd4bb,0x8d4dddb0317d6a6bf9a4dbbed3a43fa21f79869c5ab9729d239e9282,0x46873614be3dffc9218082322210c0616140286f2d160503c1a9250d,0x961bbb1fc9955a71c91a50aedcd2f14fccb660af992b0030b9c90b36,0x1c00f6d0bd405dd7d3016fb8c0c75e4ecec70fe61237f6d24008a5fd,0xeed4c3d98f1c9b9518f116263db821c36a06adae17162ad3162f68c3,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime224_pub.csv b/src/cz/crcs/ectester/data/nonprime/nonprime224_pub.csv deleted file mode 100644 index aa2ab06..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime224_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0xcfd92aea0f79190c48ca703eb8a9baa7099a23bb39578261fe4d0f04,0x257a3d98de44bd25404977a4ac7fc56d3d4e827f085b7cf5247524c4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime256.csv b/src/cz/crcs/ectester/data/nonprime/nonprime256.csv deleted file mode 100644 index 582b115..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime256.csv +++ /dev/null @@ -1 +0,0 @@ -0xc9a803b1eaf849f1c02cfd1dbfac68623985c88b37103b338ae11d2597ee8445,0x4841c5775a24a884ca36ec362b44645a2f60b25d002c4fc1d9f139870fe0cc71,0x1b097456751f3534190dae568f80a2c6ff55dddfe072a7dc6467a4b6476b6880,0xa1fd34a27afb1340b8e4a7db2a5ec5a1432c6dc8555af9f78fca2cf740cab2b7,0x98419c698cab6c7dbb53eb2751417b52ccded4680c5e09543f93c7886c3a173e,0xc9a803b1eaf849f1c02cfd1dbfac6863128c5b1fc5acd5b5e0fc0a7311fb5b1d,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime256_pub.csv b/src/cz/crcs/ectester/data/nonprime/nonprime256_pub.csv deleted file mode 100644 index 60f475c..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime256_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x75fce70968862d53e29548aad70582514e960d8128bd3c5f8c4dbe2cf8dad653,0x55aa4b7d3882fb0a83bd00c9c3bae17f1024d64aec67e1db38ef671e6350beae \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime384.csv b/src/cz/crcs/ectester/data/nonprime/nonprime384.csv deleted file mode 100644 index ffcbe91..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime384.csv +++ /dev/null @@ -1 +0,0 @@ -0xd0df6c96cff7081be80d22b005758a2e2f046e15fe020ef886e21b492ac57257a923144bcad989ab6341bd3b700f914b,0x45c64503be019afd3462b361ad2b2a3bca0aeccc5494a624fb632455e62b4f0c98f944fa97c37811da039823cd77c906,0xd85583f7f11ad23ec75ed5a414153a06d6640936b8103f5df691fa95cf2afa78f3ea5addc225b144964048c9f7592ae4,0x2b1341d12dff4f9cf9427c4752962b4c2bdc8fbcd80652516c421cc523212a01ea63c79d6e9a9c84933e353e212416ec,0xce416c6e75fa9fd205ed48fc4e3099cbb1d6ed031b7ddbff1d634eb97a83d9b780cfd4dedfdd2c7604d143196c08d933,0xd0df6c96cff7081be80d22b005758a2e2f046e15fe020ef7664ed51d7701c86bf2a1e9f3002c26fe002314c3c92f1ca9,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime384_pub.csv b/src/cz/crcs/ectester/data/nonprime/nonprime384_pub.csv deleted file mode 100644 index 236602e..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime384_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0xa4bd575bf20300b0cf8a2f41dd5a03e908966a4229a5f22f5c190d3641ac2d32b7b24a63482cbbcd0c2257f834834ef1,0x38d51c8f9e90592f567e81d0e4855e79731b5797857a4c7dc270653bc9f0c31e84693007b09cebf710d5ae3237303949 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime521.csv b/src/cz/crcs/ectester/data/nonprime/nonprime521.csv deleted file mode 100644 index b65c980..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime521.csv +++ /dev/null @@ -1 +0,0 @@ -0x01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc79cf188d9ee82d1a51c44cbd31e9cc5b816d76d5b1312b005f7b68919e275dac99f,0x00401639f36f2ee45fc164ea3e1f14f4803fd7a77ffdfb392c3f8fe95d1aea331467f4618d59aeee49d5d7c70caf320f7dd1ac166114f562413449991d3aa1a2c49e,0x004a26a8c47fce204ba953015fa86708c0de720f27523988b097e774168c15f7a215aaf18a5f1b9579ab3db935d45be14c9a87b71170396909b14d06f7a09975b3a6,0x01c880ae0a355a52791fc9600fd8b35726e9d799101489161c8f90a9c6631d09b3cb347584837d9deb8566a9c5846aded0d01eb947b4affd34e8ea7dbe733cbedafa,0x00050f12672f163f19d5d493eb82ef777b0213dd4e0cf75a9b99724fbdb54b0cc4e037bf86a48bac28467bdd936c314ce13f6ec7ec69ea09ae4f5444df4b2a117a66,0x01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc7ba0838717c1947f93cfdd3ed87ec2c2df181c7ada553346ec1495732a1e7ffe9b3,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nonprime/nonprime521_pub.csv b/src/cz/crcs/ectester/data/nonprime/nonprime521_pub.csv deleted file mode 100644 index 9695924..0000000 --- a/src/cz/crcs/ectester/data/nonprime/nonprime521_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x002844df0f31f46a40e6c7006cde99155bd5d18d0e4150178a8e307d6aec08fd02d466c03c49b49c2654b7c9a32d88ca014016a7eddd44217be915505d228efb9389,0x0105921e2172c3050ba4c9d2e744fc5b7b5e8451751e6780c6de88229497be7d23550beefa0cb7fafebb4dd9fad1244c6733befe5a97710f0dc56dc08d9d9df9d846 \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index bb555f9..aff5762 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -216,7 +216,7 @@ public class ECTester { 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. [test_suite]:\n- default:\n- invalid:\n- wrong:\n- nonprime:\n- test-vectors:").hasArg().argName("test_suite").optionalArg(true).build()); + actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. [test_suite]:\n- default:\n- invalid:\n- wrong:\n- composite:\n- test-vectors:").hasArg().argName("test_suite").optionalArg(true).build()); actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do ECDH, [count] times.").hasArg().argName("count").optionalArg(true).build()); actions.addOption(Option.builder("dhc").longOpt("ecdhc").desc("Do ECDHC, [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()); @@ -422,8 +422,8 @@ public class ECTester { case "wrong": suite = new TestSuite.Wrong(dataStore, cfg, systemOutLogger); break; - case "nonprime": - suite = new TestSuite.NonPrime(dataStore, cfg, systemOutLogger); + case "composite": + suite = new TestSuite.Composite(dataStore, cfg, systemOutLogger); break; case "invalid": suite = new TestSuite.Invalid(dataStore, cfg, systemOutLogger); @@ -739,7 +739,7 @@ public class ECTester { } testSuite = cli.getOptionValue("test", "default").toLowerCase(); - String[] tests = new String[]{"default", "nonprime", "invalid", "test-vectors", "wrong"}; + String[] tests = new String[]{"default", "composite", "invalid", "test-vectors", "wrong"}; List testsList = Arrays.asList(tests); if (!testsList.contains(testSuite)) { System.err.println("Unknown test case. Should be one of: " + Arrays.toString(tests)); diff --git a/src/cz/crcs/ectester/reader/TestSuite.java b/src/cz/crcs/ectester/reader/TestSuite.java index 7118dd8..24b72a3 100644 --- a/src/cz/crcs/ectester/reader/TestSuite.java +++ b/src/cz/crcs/ectester/reader/TestSuite.java @@ -205,21 +205,21 @@ public abstract class TestSuite { } } - public static class NonPrime extends TestSuite { + public static class Composite extends TestSuite { - public NonPrime(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "nonprime"); + public Composite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "composite"); } @Override public List run(CardMngr cardManager) throws IOException, CardException { /* Do the default tests with the public keys set to provided smallorder keys - * over non-prime order curves. Essentially small subgroup attacks. + * over composite order curves. Essentially small subgroup attacks. * These should fail, the curves aren't safe so that if the computation with * a small order public key succeeds the private key modulo the public key order * is revealed. */ - Map keys = dataStore.getObjects(EC_Key.class, "nonprime"); + Map keys = dataStore.getObjects(EC_Key.class, "composite"); for (EC_Key key : keys.values()) { EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { -- cgit v1.2.3-70-g09d2 From 4748f8bf5dfce80be5691a2b309168c19721f085 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 1 Oct 2017 02:03:20 +0200 Subject: Update the composite order curves. --- .../crcs/ectester/data/composite/composite128.csv | 2 +- .../ectester/data/composite/composite128_pub.csv | 1 - .../crcs/ectester/data/composite/composite160.csv | 2 +- .../ectester/data/composite/composite160_pub.csv | 1 - .../crcs/ectester/data/composite/composite192.csv | 2 +- .../ectester/data/composite/composite192_pub.csv | 1 - .../crcs/ectester/data/composite/composite224.csv | 2 +- .../ectester/data/composite/composite224_pub.csv | 1 - src/cz/crcs/ectester/data/composite/keys.xml | 382 ++++++++++++++++++++- 9 files changed, 377 insertions(+), 17 deletions(-) delete mode 100644 src/cz/crcs/ectester/data/composite/composite128_pub.csv delete mode 100644 src/cz/crcs/ectester/data/composite/composite160_pub.csv delete mode 100644 src/cz/crcs/ectester/data/composite/composite192_pub.csv delete mode 100644 src/cz/crcs/ectester/data/composite/composite224_pub.csv (limited to 'src') diff --git a/src/cz/crcs/ectester/data/composite/composite128.csv b/src/cz/crcs/ectester/data/composite/composite128.csv index b666e20..66b7011 100644 --- a/src/cz/crcs/ectester/data/composite/composite128.csv +++ b/src/cz/crcs/ectester/data/composite/composite128.csv @@ -1 +1 @@ -0xcfba21fd0483b1f300fa2506a5a566ef,0x36d9a5acac27a008e36cbe3e9f103fde,0xa67cf5fa09fb1db902068c87046ae21e,0x47d78391a4b9fff6a0db1292f9cd0e6a,0x9aed9c92f8bb3dbd42402165a270bd6f,0xcfba21fd0483b1f333d61a5af6ada2c7,0x1 \ No newline at end of file +0xc8bb039faeca04585e1d5864fbc05f6b,0x90af1043a837133b556495fe1e080b7c,0x916d1eaf6cc9eee0f86e5bd6313ba6fc,0xacb0cfa25821e758258ee3c7ddd37cbf,0x1fcb4b9c5c3f9a902f19130755c802b9,0xc8bb039faeca045765097266c32b334f,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite128_pub.csv b/src/cz/crcs/ectester/data/composite/composite128_pub.csv deleted file mode 100644 index a1fbe5c..0000000 --- a/src/cz/crcs/ectester/data/composite/composite128_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x63901e122761d9c16565b2f38e991f71,0xb9d99fbc3154a96ca23ecff770cbbe4f \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite160.csv b/src/cz/crcs/ectester/data/composite/composite160.csv index e685a11..a78d77c 100644 --- a/src/cz/crcs/ectester/data/composite/composite160.csv +++ b/src/cz/crcs/ectester/data/composite/composite160.csv @@ -1 +1 @@ -0xdc13490ff9857b111f44c0500770a6457e683223,0xa3ecd7d51e79d72d2700184c795aa8a6b8e66573,0x8ac43592905f995cb13f3694317bf470adafb645,0x5f8e88afc117c722859fe8e55647bca69ba82150,0x93e6dcaee271e9f2838c98b7d06eccc5d7c800e5,0xdc13490ff9857b111f446ef4a6d1e1715f6a6dff,0x1 \ No newline at end of file +0x9b0bafb73969e379b49753fa1b3cc65e9ca73adf,0x93091909c640bcdf66f470c1627ec776e9f625cc,0x69c34611c6d4cb088365ae95bf2d7d9c97aaf224,0x34e7895542e4986cd2884d9b6571cf0a955bba12,0x8ae9489212982d059b483d08a9dac6587ad67d8e,0x9b0bafb73969e379b496b7f060d2e76956ba8504,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite160_pub.csv b/src/cz/crcs/ectester/data/composite/composite160_pub.csv deleted file mode 100644 index 7060146..0000000 --- a/src/cz/crcs/ectester/data/composite/composite160_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x59c9c3c8aef29f1c1c500cafb4726da6086e6eb0,0xd695a76005eddb26afd40ee20904778bb3497bb1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite192.csv b/src/cz/crcs/ectester/data/composite/composite192.csv index c61f65c..a9fbe1f 100644 --- a/src/cz/crcs/ectester/data/composite/composite192.csv +++ b/src/cz/crcs/ectester/data/composite/composite192.csv @@ -1 +1 @@ -0xce714cc3a15ce7e5dab068c9a1f8be00aad480abccaeefc3,0x597c781f64c33eb8ef919c415911518ea323be88b9437caf,0xf81585a1b18f233d70add7ee1342d2035c386a92e3ab8320,0x150ff0a40deac6462b5987418617fdeeb6bfd76d4d60a067,0x843d577371c5dce122c2ff206b2f42fa0b842b49bdaf990f,0xce714cc3a15ce7e5dab068c9a30bc92915bd8662ae882887,0x1 \ No newline at end of file +0xabe758cde9fc09b714f543b4acac1550c09297279d4d2a1f,0x41e9bf05575d991e1e3393fc1746f2eb49e7f9b34867343e,0x54c5db9d913d1afeabce6e11ea623f8536dd6eef8eb5dfff,0xa8ee9eaafc61a1ae53da6815a644a95ccfa6c9c10de617f8,0x396ebe9cb965a02dd72f7a4f96dfc48c6ac74b49a93216d1,0xabe758cde9fc09b714f543b5567a1cda695faff0d96cbf46,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite192_pub.csv b/src/cz/crcs/ectester/data/composite/composite192_pub.csv deleted file mode 100644 index 97c66cd..0000000 --- a/src/cz/crcs/ectester/data/composite/composite192_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x17047f91dbe33032c9d09bd29ceadd8a09ccc32ac6309541,0x6a726de54fbd59cfc352e838b337fa005a97180816135e6a \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite224.csv b/src/cz/crcs/ectester/data/composite/composite224.csv index cd4c5f8..7902f2b 100644 --- a/src/cz/crcs/ectester/data/composite/composite224.csv +++ b/src/cz/crcs/ectester/data/composite/composite224.csv @@ -1 +1 @@ -0xeed4c3d98f1c9b9518f116263db770366877d12df6a9cf08b96dd4bb,0x8d4dddb0317d6a6bf9a4dbbed3a43fa21f79869c5ab9729d239e9282,0x46873614be3dffc9218082322210c0616140286f2d160503c1a9250d,0x961bbb1fc9955a71c91a50aedcd2f14fccb660af992b0030b9c90b36,0x1c00f6d0bd405dd7d3016fb8c0c75e4ecec70fe61237f6d24008a5fd,0xeed4c3d98f1c9b9518f116263db821c36a06adae17162ad3162f68c3,0x1 \ No newline at end of file +0xe6cacc569ea2a63aea0409959625c8f8238b0ddc2565046db20390ed,0x20484bda40fdcade9ff6f9147076e2824e5f0d057a4a95cfb1b9312d,0x14cacbe6ad4a700a3f6a44cdc0a60d6fd0a4f2052c5b9ae5661fd964,0x92eddfe929f73cd4088dc865bbbc33e7828c7d9c9cd7e978d226aba0,0x944111a52330a4986388b10e709ff9b1408f361cd353bed31c43ad4c,0xe6cacc569ea2a63aea04099596266ee5ef526d9cf5034d56ebedb660,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite224_pub.csv b/src/cz/crcs/ectester/data/composite/composite224_pub.csv deleted file mode 100644 index aa2ab06..0000000 --- a/src/cz/crcs/ectester/data/composite/composite224_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0xcfd92aea0f79190c48ca703eb8a9baa7099a23bb39578261fe4d0f04,0x257a3d98de44bd25404977a4ac7fc56d3d4e827f085b7cf5247524c4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/keys.xml b/src/cz/crcs/ectester/data/composite/keys.xml index 2835615..546414f 100644 --- a/src/cz/crcs/ectester/data/composite/keys.xml +++ b/src/cz/crcs/ectester/data/composite/keys.xml @@ -4,29 +4,393 @@ category="composite" desc="Points on the non-prime curves, very small point orders(3-5)."> - composite128-pub - composite128_pub.csv + composite128/1 + 0x746fa441b3a54d3c531bd59d119f400d,0x73aff68dbd96e1485cd2de0f6389cc70 + composite/composite128 + order = 3 + + + composite128/2 + 0x6e9dc37af66af0045d7a2e414d4bfb89,0x40b01d2f36c9a5b2a1cb28386dd12470 composite/composite128 order = 5 - composite160-pub - composite160_pub.csv + composite128/3 + 0x32076e371a48d82777ce851969439ab8,0xb049b7d6ba6f2d9c6ce240bc689d3556 + composite/composite128 + order = 15 + + + composite128/4 + 0xc819a68e95796650cd7d11e8ad65806f,0x280e9c9b7e5d9a5e07653ee2afac83e7 + composite/composite128 + order = 59 + + + composite128/5 + 0x66f66346d87e2214bf1bfc3331628c81,0x8c1a74b09bbbb515b027d89dcc1cecb2 + composite/composite128 + order = 177 + + + composite128/6 + 0xa546a97bd17378bd6e5c42c4ab857cac,0x13b99be68904a968a8d4ca6feab23f40 + composite/composite128 + order = 295 + + + composite128/7 + 0x6ae9f873a9da27b41e676d3514c96e56,0x8f6479493be1835cee6b9f29df21f74f + composite/composite128 + order = 885 + + + + composite160/1 + 0x37efeffb592df52c0080de1a5074505fb9bd7d6f,0x0000000000000000000000000000000000000000 + composite/composite160 + order = 2 + + + composite160/2 + 0x68684425389f5552a24b7c205e19da7a0c10a1cb,0x825ecf13c08f314cd6ad5eae73044c71e9876409 composite/composite160 order = 3 - composite192-pub - composite192_pub.csv + composite160/3 + 0x61602e67d8e17442afb37c07ea9fff2beb6c5b63,0x525e64d325c225855df22c141ab48292e2f8f937 + composite/composite160 + order = 4 + + + composite160/4 + 0x041fea694918a16ede5e6c32e24f52f7827b7942,0x0c4005ad4b02d3f04ba662cca7c5ae4de9a9ba1e + composite/composite160 + order = 6 + + + composite160/5 + 0x896db2058ec6de5bf0c3d4729449c161f3a6513c,0x168828b2d35afa6ae22cfb88470444ecfe31565a + composite/composite160 + order = 12 + + + composite160/6 + 0x5addb1c0c2b73b1c3bfa6ee1d4fa55c3d6cb79c8,0x18cf3b6fc6ac06a6af69817234799a7bed594e16 + composite/composite160 + order = 107 + + + composite160/7 + 0x2a8b120fa9fb0901280068fac4c7343c91707974,0x3c64f73118aa3e6263f988428d4f8e931c835dbd + composite/composite160 + order = 214 + + + composite160/8 + 0x09814e9b98b521aa510d24e2eb68484f9cd4f446,0x030f959368478d906bd830105e1e645f9a3e7aa7 + composite/composite160 + order = 321 + + + composite160/9 + 0x475d0927fdea77619a4c0f3d7f78fa17b1a82ebf,0x0f9ef6e4b67034f84f2568cf93bcd6244f99befb + composite/composite160 + order = 428 + + + composite160/10 + 0x441a137ed2bbe1397492bacec4d8d98e54e88fcd,0x1ba3217b753b1fd483ebd0eb6ce6642ab8f9b1d1 + composite/composite160 + order = 642 + + + composite160/11 + 0x8fcb8221093a80fe3ab7ee7ce952ae78e21177c3,0x29c944efc6e04c8a3393470be6eff62e250795c8 + composite/composite160 + order = 504 + + + + composite192/1 + 0x8220bcea81992c46bc57e0dae661eeff29e66d64b33253c5,0x000000000000000000000000000000000000000000000000 + composite/composite192 + order = 2 + + + composite192/2 + 0x94863540fdd9e8f415df79e18aee4bdd0914127581b6bb15,0x3aa760e488d12f8f93b10da531e1dbc033db25729119839f composite/composite192 order = 3 - composite224-pub - composite224_pub.csv - composite/composite224 + composite192/3 + 0x0cdf12ec0389daa5dc4fb9a877082e7acc4d7054d7eb320d,0x2a135f63802b9bb9064ffe6d319942ada312b0a06a506c68 + composite/composite192 order = 5 + + composite192/4 + 0x3d2cf1aa8ef6db0076b8e026f5f5eeb612bed45c2bf57796,0x40b1b1c78925a90c4f9c994ee9ac8a97ce8e1e5613676ec1 + composite/composite192 + order = 6 + + + composite192/5 + 0x069f245ec322d6ed422f18b4df1b2728bcff22a08c160de7,0x792466cd587549a3ffb4dbe491d54e5df25494ba9be83472 + composite/composite192 + order = 9 + + + composite192/6 + 0x649ddaeba68589618a326232704a4324957c8191fd558c60,0x9461496a59b680b82f199144c29323e061273efa62a60faf + composite/composite192 + order = 10 + + + composite192/7 + 0x319a75780c9090f769b69b082ad16dbce0e8bdbc16d04cd5,0x76b03040b524f21b3dd5008995459ca8ed35dae3722c7035 + composite/composite192 + order = 15 + + + composite192/8 + 0x77acef779d8562b4492309adf946f5970bb83190ad76a2e3,0x3e98d9c7b72a8bfd5c6f6a7c07478df003d273b1326caa6c + composite/composite192 + order = 18 + + + composite192/9 + 0x1e90f09d5328536457f6d9fe58444f086e32229007ef12fc,0x26407fbfba9f796afa97ea2c2e986d3343d711015b220f44 + composite/composite192 + order = 19 + + + composite192/10 + 0xa2e5982912dd423cfb745a01088e540b41e19ba84107cddc,0xaa29fc9dd974238b9daf73997d3c4dd331584d87356f9549 + composite/composite192 + order = 30 + + + composite192/11 + 0x670c2e74df1cf4f473ab37ef685b2a915858863bc9c67868,0x2edc6b47a9fbe500c2f4f4b79bb44b229dd99194aca26d5a + composite/composite192 + order = 38 + + + composite192/12 + 0x14c936965c39188192d431aaf96f37e0d398b5a858933b3c,0x19c6526df20625d92445007603f19dd120702351869f9ae3 + composite/composite192 + order = 45 + + + composite192/13 + 0x595694d6d70b13b372b2f1b4daf5ffd391513d9542b0d600,0x099f0ac0ce38d9920f3c59a63433230f4f945716c8d246f9 + composite/composite192 + order = 57 + + + composite192/14 + 0x09cf293ad9517ef1932fb81a4800d60a768356fd2980ae77,0x1b12ab568cb4ac07593bb7cd6bc8a9364bac3c345419026f + composite/composite192 + order = 90 + + + composite192/15 + 0x9424bf6ba15758fc88df622be2a7055ebd34bb0e8e89c945,0x2611aaf3752880c39238f669d910ca591358e5aa06f95119 + composite/composite192 + order = 95 + + + composite192/16 + 0x4289f802fa238ded56eda2164532f205cdde5b9ba58b8226,0xa2e1cdff2ae8312f4882ff44e4ef1d9e16be424fecd624e3 + composite/composite192 + order = 114 + + + composite192/17 + 0x5cabb4f80e166127067104af1327a8531c053ec510702d6a,0x2fdd3945ffdde5e5389ff43ec323031f9c39b795fbb9f41b + composite/composite192 + order = 171 + + + composite192/18 + 0x9a6f5c897b695025e86d74043bf6a5a2bdf38ea7e2fe8f0e,0x4367779cadb1f8a193ac73dc51293aa0e94e930456e89692 + composite/composite192 + order = 190 + + + composite192/19 + 0x30f786b7a6a3292c40a1a2ac6934646595787c4f003a08c3,0x84e4b9970c123d1f5188fca8f27152d377d85f2352543992 + composite/composite192 + order = 285 + + + composite192/20 + 0x042d015cd6633de4ed1700c346774ae17263b3e284b43162,0x7c27c4593d37115d93bfd33797ae73f0805117b032289e46 + composite/composite192 + order = 342 + + + composite192/21 + 0x9f62978f1018599e5139fa6560fe3a39c108674f361b1389,0x884e25851a5de235df686fbb870e6b7b81accb8bbc63cd15 + composite/composite192 + order = 570 + + + composite192/22 + 0x29d846d8f363bc58149fdf6eaced9dbc7692a0942f6ecabb,0x784af0c66238ef9cdf900eee2fdce8081d2aa59dd327c8c3 + composite/composite192 + order = 855 + + + composite192/23 + 0x3c6d33801293213a71f4a7d9b1091cabb89bcf7fc266084e,0x80eb1f866a3774c45811feaee8cda2f020e5aec70a2b5233 + composite/composite192 + order = 1710 + + + + composite224/1 + 0x14f89a6ef687659649fd6e0e6cb1f7f27c0f9f94fc872e7f54a9c856,0x00000000000000000000000000000000000000000000000000000000 + composite/composite224 + order = 2 + + + composite224/2 + 0xb4fbabc7cf96b62b08edbaa2df53346bbb871c121bbb35e771c74db5,0x61cf8b556f068f45ec69963964a0e8ab72c1fa0be48e2ea886235956 + composite/composite224 + order = 3 + + + composite224/3 + 0x5b98ef6f104d0cc4159cc793d52713bafbc2b37a9f64af8f962b1c5a,0x7935aef16b1cb800beca9ab322aa8ecf8281f870057a8e1fbdd72490 + composite/composite224 + order = 4 + + + composite224/4 + 0x3abe85a7ef34758c487373eb1f193a86f2b073b23a42ab3753596308,0xca9743c8ebf2fe6ceb300b93e0742ebe5f594b2ed84dba7f42f7aedc + composite/composite224 + order = 6 + + + composite224/5 + 0x3b931bbe008a038b5a5b03cf34c4102ba919579bd0a81f066193ab76,0x794f623ed1525010559240ad899b19a841bbbb818a64f32fc28c9931 + composite/composite224 + order = 8 + + + composite224/6 + 0x6ca8b206ce077be28ff56c18295508ade9fce4a051d4975d61ee84d0,0x1f5720ccc870e31e83eb58f7c7c5ada471f7502ae5b2d87a69109df7 + composite/composite224 + order = 12 + + + composite224/7 + 0x45437959ee88358cd8ee9902139cf6c9eee124c8ee199bd1a1ecc2da,0x756ad18b140d6a13a010fc21f1c4cf45a67eeb4c3dd4b202e9ae775f + composite/composite224 + order = 16 + + + composite224/8 + 0xd2074198f477e79a92918d4a5bc0ba104de4b0369104a8b51012595d,0x5025127d318e3c34e4fbbefb397874a3ed50a9cfd6ca455d4be02125 + composite/composite224 + order = 24 + + + composite224/9 + 0x4513ad86e9415caae932018d67c869dbbe001cd53e64d82d205f4e2a,0x130dbd3e71618ddb0464bf3e894c30e1dd3bc25bb01e09e5b50a001d + composite/composite224 + order = 29 + + + composite224/10 + 0x2f4f470b72c093667e3f433a5189988adbb0fe1ae36482c3eeecf8a4,0xc1ac6c167ff41b0842f6470bac49d2a518da6c4c456c5657be15dec6 + composite/composite224 + order = 32 + + + composite224/11 + 0x58741bd7ac127ecf8aa7c9fd78d22d81f8c10bb971bb77c015f69cd6,0x52e914fc15edb4af4a53ebeaf8466d2b7cf1bfe4a78c036a8faa5cdf + composite/composite224 + order = 48 + + + composite224/12 + 0x7a06eeb07784de6a15d1322243b4edbe24eb9d24869e1d9b7b883686,0xba5f157579eda39cc85cf04cd48f710133716a0fa0f5a48c3948381c + composite/composite224 + order = 58 + + + composite224/13 + 0x67d78ae1eaa30a898a3497c0cff43675be6d8cd4e41971661e8622b8,0x2e7337490aa8220d721167f7d047952af1d68615b07619607c771f5d + composite/composite224 + order = 87 + + + composite224/ + 0x30eea9b5158e7ba9ba6a2a955942e3324c6539a70e78270abe43f7fd,0xb3eb76bbcac6cd68e28688d70f431d26147bbb380bf1938d8038418e + composite/composite224 + order = 96 + + + composite224/14 + 0x4a27a6d15ecdfa776161aa180a4cd2de898610aac1b274f7a85d7ef1,0xd92847404473b63060e1514fe6a431130a79512c867d89eda0e3c674 + composite/composite224 + order = 116 + + + composite224/15 + 0x6a7ed0907ecee744da1a57ec48ff6cfc0d8d77c67a585fd9750081e6,0x96106e57beafd660a8622f6341967fd4565ce9f4f09793cc3f287316 + composite/composite224 + order = 174 + + + composite224/16 + 0x52c53640843d85f9945b18452a96e48816bbb52c76d012b3bd197f79,0x9630aba4de01758e0aaddef1de1cfb070af629f80c3ad3bb21e3cce5 + composite/composite224 + order = 232 + + + composite224/17 + 0x88166b34bee1151dc0589da4bed6da8c6a2e9d4c78eb4ef21c5a9efd,0xbb92af84b1faffb9cbd516316e2c58dabd3867c5ac4dccb4b3d7c25c + composite/composite224 + order = 348 + + + composite224/18 + 0x02edb51c0bc83b37cc89d2a7eab42719f0c847d61334022b6ca765c6,0xe08729140e552810499c414488de5751769d595940be05992e1e2977 + composite/composite224 + order = 464 + + + composite224/19 + 0x96967cf6b0ae919e50f815ac8ebcc35d0625b518d3fd095224b3c70a,0xd7d51361df21536593163d588bb4843a3ea53bfb114e43afa5eae2fb + composite/composite224 + order = 696 + + + composite224/20 + 0xb2b0a8e35a9597549a98a150f2b2a311feb560c99923e5ad23befcfa,0x6275928b50ccfd639b81c77c65a8d016c7ea4a035975e871dd10ef5d + composite/composite224 + order = 928 + + + composite224/21 + 0xd22b61d5ba5ee04d963bedcbb11165c23990b7053e5d9aef656eb078,0xa000d64563591df0b2f9e270247bca57b242e70f58ed57b4a8acec2e + composite/composite224 + order = 1392 + + + composite224/22 + 0x1f126f0463995cd293799fc58cb3efa1459a539cbd2d88c8d7283cfc,0x51175df02b5884fce8bfd17a7a97ccf12a5fdfdec4c297b301e477cc + composite/composite224 + order = 2784 + + composite256-pub composite256_pub.csv -- cgit v1.2.3-70-g09d2 From 209b13aeef08a641e3ffc82c58ef7bac9dc8fe35 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 12 Oct 2017 20:20:13 +0200 Subject: Update composite curves 384 and 521 with new data. --- .../crcs/ectester/data/composite/composite256.csv | 2 +- .../ectester/data/composite/composite256_pub.csv | 1 - .../crcs/ectester/data/composite/composite384.csv | 2 +- .../ectester/data/composite/composite384_pub.csv | 1 - .../crcs/ectester/data/composite/composite521.csv | 2 +- .../ectester/data/composite/composite521_pub.csv | 1 - src/cz/crcs/ectester/data/composite/keys.xml | 174 ++++++++++++++++++++- 7 files changed, 169 insertions(+), 14 deletions(-) delete mode 100644 src/cz/crcs/ectester/data/composite/composite256_pub.csv delete mode 100644 src/cz/crcs/ectester/data/composite/composite384_pub.csv delete mode 100644 src/cz/crcs/ectester/data/composite/composite521_pub.csv (limited to 'src') diff --git a/src/cz/crcs/ectester/data/composite/composite256.csv b/src/cz/crcs/ectester/data/composite/composite256.csv index 582b115..7769ef2 100644 --- a/src/cz/crcs/ectester/data/composite/composite256.csv +++ b/src/cz/crcs/ectester/data/composite/composite256.csv @@ -1 +1 @@ -0xc9a803b1eaf849f1c02cfd1dbfac68623985c88b37103b338ae11d2597ee8445,0x4841c5775a24a884ca36ec362b44645a2f60b25d002c4fc1d9f139870fe0cc71,0x1b097456751f3534190dae568f80a2c6ff55dddfe072a7dc6467a4b6476b6880,0xa1fd34a27afb1340b8e4a7db2a5ec5a1432c6dc8555af9f78fca2cf740cab2b7,0x98419c698cab6c7dbb53eb2751417b52ccded4680c5e09543f93c7886c3a173e,0xc9a803b1eaf849f1c02cfd1dbfac6863128c5b1fc5acd5b5e0fc0a7311fb5b1d,0x1 \ No newline at end of file +0xdc42862158cdcfc8fbe8c4ec28b02e0e12624ebc15f6486163df218253e1b953,0x01f355375dac7e69cc12c22ce747782bf998252f1c9c9c983273bc2b7e721461,0x22098140e10d5d88bcc96a558500a022d0252bfbe438d3475ef2d90261fe3b1f,0x3826ea1bacb3a90c653302db7fb7e6db4ea8d4f62e68eff73272d79fe61cfd8b,0x4ecd7019f52f3103f7810639f13cfc82fa52b47ad37d29a316bc052fbedde067,0xdc42862158cdcfc8fbe8c4ec28b02e0f78ce34249a0454ca049ad0ef7c2fcfea,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_pub.csv b/src/cz/crcs/ectester/data/composite/composite256_pub.csv deleted file mode 100644 index 60f475c..0000000 --- a/src/cz/crcs/ectester/data/composite/composite256_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x75fce70968862d53e29548aad70582514e960d8128bd3c5f8c4dbe2cf8dad653,0x55aa4b7d3882fb0a83bd00c9c3bae17f1024d64aec67e1db38ef671e6350beae \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite384.csv b/src/cz/crcs/ectester/data/composite/composite384.csv index ffcbe91..7516301 100644 --- a/src/cz/crcs/ectester/data/composite/composite384.csv +++ b/src/cz/crcs/ectester/data/composite/composite384.csv @@ -1 +1 @@ -0xd0df6c96cff7081be80d22b005758a2e2f046e15fe020ef886e21b492ac57257a923144bcad989ab6341bd3b700f914b,0x45c64503be019afd3462b361ad2b2a3bca0aeccc5494a624fb632455e62b4f0c98f944fa97c37811da039823cd77c906,0xd85583f7f11ad23ec75ed5a414153a06d6640936b8103f5df691fa95cf2afa78f3ea5addc225b144964048c9f7592ae4,0x2b1341d12dff4f9cf9427c4752962b4c2bdc8fbcd80652516c421cc523212a01ea63c79d6e9a9c84933e353e212416ec,0xce416c6e75fa9fd205ed48fc4e3099cbb1d6ed031b7ddbff1d634eb97a83d9b780cfd4dedfdd2c7604d143196c08d933,0xd0df6c96cff7081be80d22b005758a2e2f046e15fe020ef7664ed51d7701c86bf2a1e9f3002c26fe002314c3c92f1ca9,0x1 \ No newline at end of file +0x91520c5e44d7a5e9c673943d2fc502d2b35a1c9edc6189da10277423d7381fd4671fc706ff1dce6f8513317842fb655b,0x6c64adff869b4e0b9f0dd35945b24e3ab389232b1e506a71306e389dddbf43ec6c73d290fab04976da246fd77a7e28dd,0x4004c33e4f8b4de57064543802ca11810c79aa9990796d5750dba07f3e4e98f3dd18b3abe052208741149c3ad0fe6f56,0x39bf2e7d67ad506e074e04c1b73a4add511b0579cdae07bd6c025c703ee31ff33c0445c2cb10e465f0f453d996751e4e,0x667ec38866be3e87229e31e6dabc2444e2603e8118c0316e592571e9a904423e4792c18c0360ae57fcdaec87901d2e0b,0x91520c5e44d7a5e9c673943d2fc502d2b35a1c9edc6189db347c42a7d0924b7cd1414d57f582a4b96177c911e9bb3ddd,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite384_pub.csv b/src/cz/crcs/ectester/data/composite/composite384_pub.csv deleted file mode 100644 index 236602e..0000000 --- a/src/cz/crcs/ectester/data/composite/composite384_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0xa4bd575bf20300b0cf8a2f41dd5a03e908966a4229a5f22f5c190d3641ac2d32b7b24a63482cbbcd0c2257f834834ef1,0x38d51c8f9e90592f567e81d0e4855e79731b5797857a4c7dc270653bc9f0c31e84693007b09cebf710d5ae3237303949 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite521.csv b/src/cz/crcs/ectester/data/composite/composite521.csv index b65c980..0cf36e7 100644 --- a/src/cz/crcs/ectester/data/composite/composite521.csv +++ b/src/cz/crcs/ectester/data/composite/composite521.csv @@ -1 +1 @@ -0x01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc79cf188d9ee82d1a51c44cbd31e9cc5b816d76d5b1312b005f7b68919e275dac99f,0x00401639f36f2ee45fc164ea3e1f14f4803fd7a77ffdfb392c3f8fe95d1aea331467f4618d59aeee49d5d7c70caf320f7dd1ac166114f562413449991d3aa1a2c49e,0x004a26a8c47fce204ba953015fa86708c0de720f27523988b097e774168c15f7a215aaf18a5f1b9579ab3db935d45be14c9a87b71170396909b14d06f7a09975b3a6,0x01c880ae0a355a52791fc9600fd8b35726e9d799101489161c8f90a9c6631d09b3cb347584837d9deb8566a9c5846aded0d01eb947b4affd34e8ea7dbe733cbedafa,0x00050f12672f163f19d5d493eb82ef777b0213dd4e0cf75a9b99724fbdb54b0cc4e037bf86a48bac28467bdd936c314ce13f6ec7ec69ea09ae4f5444df4b2a117a66,0x01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc7ba0838717c1947f93cfdd3ed87ec2c2df181c7ada553346ec1495732a1e7ffe9b3,0x1 \ No newline at end of file +0x01c230ff4a64e33ad6da8361c7e2bf2a85e4ad5e88f8e3e8e7e3c42a6b9c9883b3690e2f82b38a684e823a257b3d5c4c2d7c34bfcb937fe5658c77247b28bc90c6af,0x00852cf32173a9b3a8a2316bbe6ba0b98efcc41247a17a8aead02ccc7cb90870daccd10a44e9385abf0d0ae175fa03c0facab1d2069b79795f36d10ce25430676805,0x0174e20e49d5970117cdfc61c0a0ae062519c0c4d577f42e0d3f1cd443732b8e62deb34922a4a6d85b8b7f6df61dadffec95c17babbfaf5c57598033be0b1a44e32f,0x01b1dbc5bd175cbd8699895698b10d047853679f048261094854134de1d6a81ffdd1cc31ede64293c9bee543ad2113c164bd1da92f5c3aa7ba7f0378bdb58251d870,0x0188b8c020cc1504eedb4fb859e40b8031cb26d9273efa2578bf7da01db994cf2a5cf2780b9a7ff6d33210b962ae20c56f71b7fa2b36deef33d7d675c6136acd73c1,0x1c230ff4a64e33ad6da8361c7e2bf2a85e4ad5e88f8e3e8e7e3c42a6b9c9883b36ec447771e871c188d3f04a4e407f1d659335dd0e351bd7f3f76a639726d6dc0d2,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite521_pub.csv b/src/cz/crcs/ectester/data/composite/composite521_pub.csv deleted file mode 100644 index 9695924..0000000 --- a/src/cz/crcs/ectester/data/composite/composite521_pub.csv +++ /dev/null @@ -1 +0,0 @@ -0x002844df0f31f46a40e6c7006cde99155bd5d18d0e4150178a8e307d6aec08fd02d466c03c49b49c2654b7c9a32d88ca014016a7eddd44217be915505d228efb9389,0x0105921e2172c3050ba4c9d2e744fc5b7b5e8451751e6780c6de88229497be7d23550beefa0cb7fafebb4dd9fad1244c6733befe5a97710f0dc56dc08d9d9df9d846 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/keys.xml b/src/cz/crcs/ectester/data/composite/keys.xml index 546414f..f333042 100644 --- a/src/cz/crcs/ectester/data/composite/keys.xml +++ b/src/cz/crcs/ectester/data/composite/keys.xml @@ -392,21 +392,179 @@ - composite256-pub - composite256_pub.csv + composite256/1 + 0xadd83091be650ca4d78b81c1ae2851a9197a5fe33a136d368ecbb1fe06200764,0x0000000000000000000000000000000000000000000000000000000000000000 composite/composite256 - order = 3 + order = 2 + + + composite256/2 + 0x8ca20dd1fa045339a171513fb1daa25fa7439e4b97c129c6039e4b9abbac1532,0xb565bde8fe9831f0bce07d70784dc1b7064c443b54b5e96408c1942e30437cc3 + composite/composite256 + order = 5 + + + composite256/3 + 0x7f25698dc1a9a0810dbd97e1918ea4a78f20783ce3ed4133df0fe6f66fe29c3f,0x0eff3a76e05d5e24b6b57c13f704ea2a54750502000c9d3f04d1ad932cfb6d3e + composite/composite256 + order = 10 + + + composite256/4 + 0x8b6be31db337293200eb7a6a2ac144374223a4f76ea7b003eb789d0622cbc806,0xd9556692a39eb79d29c0a019d94f88737edd90006f55ecdc1ac204c81eb0c32b + composite/composite256 + order = 17 + + + composite256/5 + 0x497170999460d32516062fa49929789e645a46e2db216e83a7f738d2c5c482d6,0xa1666de87f4f0de0ed523a962d386349d87b4e40c7c6db555e52e33da3de738b + composite/composite256 + order = 34 + + + composite256/6 + 0x409a4d05651cfa87af444fa58f9d3fa3d5bbd25a8c9f7a6be200b5255bb06bac,0x3a08b088284a3da5c59246379b9b7aa36a86917f58c390cc49d2172e33d5c094 + composite/composite256 + order = 85 + + + composite256/7 + 0x5ebd412e2785d08f2fd0403a3df2d028a4c33c887637d75ce05543cb6c33f172,0xa3f76e00200df483e710db5724c08ef01f813959ae3205b5e4e3c7a051d303b8 + composite/composite256 + order = 170 - composite384-pub - composite384_pub.csv + composite256/8 + 0x756ab6f97c43c68c38c8070766c3d86df422f8bc9c8e5ff8e8fee0af683b58e0,0x08746e1b87c5e8e582fa8a4e13b5971728af1e6c6f74a28478b0a606357c17b4 + composite/composite256 + order = 289 + + + composite256/9 + 0x0e02b7a9def8eb46986ad908a49109267beb19e331bc399eb036ec087c2081c5,0xa1e1fff1a84a3b131c072f76c1ed54293f5d82dc5c9c78c9984786648d172cb2 + composite/composite256 + order = 578 + + + composite256/10 + 0x5330e8ad3035f2b256091a362313ae5b7f183d11c3fce1528443cf2626911e09,0xb3abb61c1ac189a3980f8c6dfc4330997096dca089273000a7302682b40ff6bc + composite/composite256 + order = 1445 + + + composite256/11 + 0x31f4f374d564ec73cd4e066ec84cdfa89be9389c2c0e557d0226af8f4a960768,0xba1b2169c90ea6cf612db29e4142c1483f9268012114148e28d35969669a7549 + composite/composite256 + order = 2890 + + + + composite384/1 + 0x5136c182f03241ec87e6eec1728c1fb2d6b2ddcd4d9abf2a110c337419c4ec7cc8386b7b9ea9f5cb18b0f3c2a78e6489,0x9130cb73f8064fddb24d8c6a216b57fe99df93bcc82c93343617a5246ca1643fe57a06d6112a1791d1bd3643fbd9c041 composite/composite384 - order = 3 + order = 5 + + + composite384/2 + 0x20070cc3e17bf1c770ef297b679c54d6454a3cd5effd94e236677b10e3e8075a8a9902ecd71e930f19fda4d79931502d,0x04a21190dbba4b6efe62640887256163ba5c9fa706aad74f1bfebdc27ca6f9e2f9b37bf9abf2c72803968799e2c7e702 + composite/composite384 + order = 11 + + + composite384/3 + 0x6d24691bacf187946f24885f2bec9a6b09239f4b7d93651c8c62f0221ba695baa5f70c49028ca5bc462289edcec081fe,0x7489fb2fd719c84ab0a12eed6f5f45fabb7c19d49d9d185a4d4efcffc9d2110a1b5a04961251f1ab19908662c8dadc9a + composite/composite384 + order = 55 + + + composite384/4 + 0x0c5dccdb9c83f4d3cad69213b80f2c969210a228b85dce49c8a31ad08cf232118c6eb03d3b7e3d7bc8add230c24d184b,0x6316b45ee6832912cf3d54fc1fb73de47753ed225074cf76ebcdecb5f0c797e166b90767e2f267a4ea6b43cf6cde23c1 + composite/composite384 + order = 61 + + + composite384/5 + 0x32a43b215a94626d6f28974d5622469ebbdb7a54fef268267066fa3199f343f044248f39bf6ef10bdfffa6cb80155bb7,0x3d6a14e4bfec02b2306649a6da4fbbac157cecb3faa6cc9e62b5a469ea7f17a6f5e66a7c6753eee3f9cb7bdd4d0f8a4c + composite/composite384 + order = 305 + + + composite384/6 + 0x5baac92f9d31ffd1cf982566f6d4bc239350ffae1f6b068ec07fb200795f4a902978d080a70d5908bd8ee283723ee196,0x164584fff8bb749bb781eedc62f9a39f658490969d24bff24b5c91f7af7eb7dd967b0066daf54678788f241b67d1a78b + composite/composite384 + order = 671 + + + composite384/7 + 0x3b2d81fd9001d4b208e9d6312553bc3c2ca0853145dd882188b4b197152faca8f1194826c745f74c90d96594dcc0794b,0x8fef63c95e804b6ab0bbe7142bb56ecaa24737e8f97466d68f0c9ca7c230480b28d958d69277fcbcd77f6a566423ddec + composite/composite384 + order = 3355 + + + + composite521/1 + 0x01221fb007e1c2f7413b4d79a0265baf9d9ea2850e9e262b28ef5ead6f5f505d05cf731a891a443e7c1a35c867d7a3de4118f76d1cb68f6479eb85fe87fc9c6be098,0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + composite/composite521 + order = 2 - composite521-pub - composite521_pub.csv + composite521/2 + 0x00a4b42ad90c0e3f7e342d8d661b4d5162ab7928b4938ab660b2e6fea3213c5d4b420123f65141a8eb7b4a46173bfce6ea1577df94f6f934f72d459c4dd3c0ef038e,0x003316c4b6c5c6b3ab3eee7f1ff365cce6045fdc43d4e6c64efa7789f2626676b47b488e6612d291d60d4a788ddd2e8b1aa8bfff02e105a285532a20ac08fa1088e7 composite/composite521 order = 5 + + composite521/3 + 0x0039ccb35a071951bda5c9c40edb1fbfa365ce59a2a89ee37739708d748cc66bb19cbcfa30cc4ef6bfbb48728e930d940e30c64b6d77c0e64c79c1bad49540084662,0x00d7016bd5016c8ba9601ec3dd44f77b8ff7bb3aaa6c358ac78bf931f7f4d140e4de1912c343bfe7956ab0b29aa9ec0922008d025e9895a8141bd7c88f913e745e29 + composite/composite521 + order = 10 + + + composite521/4 + 0x00426f8691e7f8afc0f7443206d3d44779b96c942714386733853530d3af4944e1ad38c7c1047f50e2bf8db7dfc0d4a8803976da934eaaa19e478ee026736ae8ac6d,0x00c97e0d2dedcd7b601430f1b8959c26c24918f6c9bd803bfe8cc015e7285956f878f27a33c91f64fec051f478cadcb7ed80c21127a7916d1e2c88ee921f1f65cf94 + composite/composite521 + order = 25 + + + composite521/5 + 0x001550be76b460f82f2fbf3ebfd9709c50c07ec18c250c01b7d934eda2bcf3b78f648b7dd813cfd58a3f12ab35ad015c03ed0e14af6ef1560706dd59fafc32ecd5aa,0x00eb5368f5c53f70d88bbb1f31afe0d730aac4523b998043b2029a441528f7ae3483773117184e8d2efc875fe5447b0eb4ffb781bb014c67505434477fc4d6e343cd + composite/composite521 + order = 31 + + + composite521/6 + 0x016bad260ce10570e179138810152059e4ed8d1a6f5d8f8f2697ff98e8a1d8400cb5fb2334e5ccd88c3933add314e1f94b67ce99a4594da7754b39d58262c2275827,0x004a9b47353f119a01bb8dff6f63b58499a83c20a6fb8cbf84e717e35643c23eefef157891ca720b332355b70ee265bad5e057958ee42ab6a0f0675aa85caaad4a8d + composite/composite521 + order = 50 + + + composite521/7 + 0x01320c8762348be979ddf729b42a3839bd8e6a99923b3bab663dbb298f470d0e3aac375a1d1aa7119ec5b2e82c7921f192bea4ac81b7259af3a417135e82ad56aa4b,0x01c0be727f0480ea5137efc3fd201fca223ecd58d34dcc31cbfd6b7909b3033bb7d65e006e4dfe7c80f2a75d0bb5256986077d16cdd3c4d74bddfedc700c5be39541 + composite/composite521 + order = 62 + + + composite521/8 + 0x0097c707694d550fe1533a9ce461e0317206385ee961cc3c646cbe84afc17a426023c8dd1e8db9df81bfd01b8cd123fd381c7fffd375f1776eb69994c94d67088ddc,0x00f3c16b5bb57044a555c5c89dc0fe1d2dec3406a645e66811d9a466a687884133cb9863394ddb19e2888d1f311d88060b0601f960d8a2ba86f67b4e1c8dad61326b + composite/composite521 + order = 155 + + + composite521/9 + 0x014ae6ee5a69767d8abb24d62d0435807e36d9c42572eeb2a7d2852837f68d62dd97c4ae4ed4b47f1208e9b80c0e285b69db277be2072e104b1892892be5e09d1d6a,0x0008a34156d7f671159b1bd85ab0413092fb16de8a6ea9ddae20c427262d2636b926339bf1ad1a2a1518aba13d3ce858f7b232971ebdb3b54b61e1273defd0c20ba7 + composite/composite521 + order = 310 + + + composite521/10 + 0x00f6d940ce18d53a7706999da53c40cb8e4581a73069ae4358747257a169ab1532474b43e506603fcbd743b63b48551faa3bcac5fb1a40ca2b3f49f369fec36b7c7d,0x00f881dbc0ab0b74c20db84810eb476b1fb852398e87f8d909873f0b73cce0166baf43f07487a7a35a172000f5050c8531b108afb03c2654fa4a81b0538b58c4ddb1 + composite/composite521 + order = 775 + + + composite521/11 + 0x0012538aae315d49a9b443382a19de468f57c7ff2494ecbaa54e927d3affb6d1d6503cb3acfbb0feee44caeb7fbef8804ac073c709a90eb3c7464a6644c9c5581e9b,0x01afeb2c9e1b519804e3a73364953368f915e6abc765adbd3ec7cfc2b808b1b4b46d575a664d06b4b455850cf295fd69eb823ca069cd2de90542db1496ad9095fad4 + composite/composite521 + order = 1550 + \ No newline at end of file -- cgit v1.2.3-70-g09d2 From d5a549b382db10c34eea35e571b1ba8056eaa5da Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 13 Oct 2017 21:23:51 +0200 Subject: Init and print EC_Key/EC_Keypair id when available. --- src/cz/crcs/ectester/data/EC_Store.java | 6 +++--- src/cz/crcs/ectester/reader/ECTester.java | 2 +- src/cz/crcs/ectester/reader/ec/EC_Key.java | 15 +++++++++------ src/cz/crcs/ectester/reader/ec/EC_Keypair.java | 5 +++++ 4 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index 94eb011..9b1f5bb 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -266,11 +266,11 @@ public class EC_Store { EC_Params result; if (elem.getTagName().equals("pubkey")) { - result = new EC_Key.Public(curve.getTextContent(), descs); + result = new EC_Key.Public(id.getTextContent(), curve.getTextContent(), descs); } else if (elem.getTagName().equals("privkey")) { - result = new EC_Key.Private(curve.getTextContent(), descs); + result = new EC_Key.Private(id.getTextContent(), curve.getTextContent(), descs); } else if (elem.getTagName().equals("keypair")) { - result = new EC_Keypair(curve.getTextContent(), descs); + result = new EC_Keypair(id.getTextContent(), curve.getTextContent(), descs); } else { throw new SAXException("?"); } diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index aff5762..ea2cbe4 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -615,7 +615,7 @@ public class ECTester { public boolean simulate = false; public boolean yes = false; - //Action-related ions + //Action-related options public String listNamed; public String testSuite; public int generateAmount; diff --git a/src/cz/crcs/ectester/reader/ec/EC_Key.java b/src/cz/crcs/ectester/reader/ec/EC_Key.java index e1adcf1..5077d5b 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Key.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Key.java @@ -22,11 +22,6 @@ public class EC_Key extends EC_Params { this.desc = desc; } - private EC_Key(String id, short mask, String curve) { - this(mask, curve); - this.id = id; - } - private EC_Key(String id, short mask, String curve, String desc) { this(mask, curve, desc); this.id = id; @@ -53,9 +48,13 @@ public class EC_Key extends EC_Params { super(EC_Consts.PARAMETER_W, curve, desc); } + public Public(String id, String curve, String desc) { + super(id, EC_Consts.PARAMETER_W, curve, desc); + } + @Override public String toString() { - return "EC Public key, over " + getCurve() + (getDesc() == null ? "" : ": " + getDesc()); + return "<" + getId() + "> EC Public key, over " + getCurve() + (getDesc() == null ? "" : ": " + getDesc()); } } @@ -72,6 +71,10 @@ public class EC_Key extends EC_Params { super(EC_Consts.PARAMETER_S, curve, desc); } + public Private(String id, String curve, String desc) { + super(id, EC_Consts.PARAMETER_S, curve, desc); + } + @Override public String toString() { return "<" + getId() + "> EC Private key, over " + getCurve() + (getDesc() == null ? "" : ": " + getDesc()); diff --git a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java b/src/cz/crcs/ectester/reader/ec/EC_Keypair.java index e7da027..2643346 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Keypair.java @@ -21,6 +21,11 @@ public class EC_Keypair extends EC_Params { this.desc = desc; } + public EC_Keypair(String id, String curve, String desc) { + this(curve, desc); + this.id = id; + } + public String getCurve() { return curve; } -- cgit v1.2.3-70-g09d2 From e78bd5d010bd6ced2b71d83b88748f9cc8d98d5e Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 13 Oct 2017 21:42:49 +0200 Subject: Reorganize reader packages. --- src/cz/crcs/ectester/reader/Command.java | 588 -------------------- src/cz/crcs/ectester/reader/ECTester.java | 3 + src/cz/crcs/ectester/reader/Response.java | 591 -------------------- src/cz/crcs/ectester/reader/Test.java | 82 --- src/cz/crcs/ectester/reader/TestSuite.java | 314 ----------- src/cz/crcs/ectester/reader/command/Command.java | 592 +++++++++++++++++++++ src/cz/crcs/ectester/reader/response/Response.java | 591 ++++++++++++++++++++ src/cz/crcs/ectester/reader/test/Test.java | 85 +++ src/cz/crcs/ectester/reader/test/TestSuite.java | 320 +++++++++++ 9 files changed, 1591 insertions(+), 1575 deletions(-) delete mode 100644 src/cz/crcs/ectester/reader/Command.java delete mode 100644 src/cz/crcs/ectester/reader/Response.java delete mode 100644 src/cz/crcs/ectester/reader/Test.java delete mode 100644 src/cz/crcs/ectester/reader/TestSuite.java create mode 100644 src/cz/crcs/ectester/reader/command/Command.java create mode 100644 src/cz/crcs/ectester/reader/response/Response.java create mode 100644 src/cz/crcs/ectester/reader/test/Test.java create mode 100644 src/cz/crcs/ectester/reader/test/TestSuite.java (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java deleted file mode 100644 index cf05972..0000000 --- a/src/cz/crcs/ectester/reader/Command.java +++ /dev/null @@ -1,588 +0,0 @@ -package cz.crcs.ectester.reader; - -import cz.crcs.ectester.applet.ECTesterApplet; -import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.data.EC_Store; -import cz.crcs.ectester.reader.ec.EC_Curve; -import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.ec.EC_Keypair; -import cz.crcs.ectester.reader.ec.EC_Params; -import javacard.security.KeyPair; - -import javax.smartcardio.CardException; -import javax.smartcardio.CommandAPDU; -import javax.smartcardio.ResponseAPDU; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public abstract class Command { - CommandAPDU cmd; - CardMngr cardManager; - - Command(CardMngr cardManager) { - this.cardManager = cardManager; - } - - public CommandAPDU getAPDU() { - return cmd; - } - - public abstract Response send() throws CardException; - - public static List sendAll(List commands) throws CardException { - List result = new ArrayList<>(); - for (Command cmd : commands) { - result.add(cmd.send()); - } - return result; - } - - - /** - * @param keyPair which keyPair/s (local/remote) to set curve domain parameters on - * @param keyLength key length to choose - * @param keyClass key class to choose - * @return a Command to send in order to prepare the curve on the keypairs. - * @throws IOException if curve file cannot be found/opened - */ - public static Command prepareCurve(CardMngr cardManager, EC_Store dataStore, ECTester.Config cfg, byte keyPair, short keyLength, byte keyClass) throws IOException { - - if (cfg.customCurve) { - // Set custom curve (one of the SECG curves embedded applet-side) - short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; - return new Command.Set(cardManager, keyPair, EC_Consts.getCurve(keyLength, keyClass), domainParams, null); - } else if (cfg.namedCurve != null) { - // Set a named curve. - // parse cfg.namedCurve -> cat / id | cat | id - EC_Curve curve = dataStore.getObject(EC_Curve.class, cfg.namedCurve); - if (curve == null) { - throw new IOException("Curve could no be found."); - } - if (curve.getBits() != keyLength) { - throw new IOException("Curve bits mismatch: " + curve.getBits() + " vs " + keyLength + " entered."); - } - if (curve.getField() != keyClass) { - throw new IOException("Curve field mismatch."); - } - - byte[] external = curve.flatten(); - if (external == null) { - throw new IOException("Couldn't read named curve data."); - } - return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external); - } else if (cfg.curveFile != null) { - // Set curve loaded from a file - EC_Curve curve = new EC_Curve(null, keyLength, keyClass); - - FileInputStream in = new FileInputStream(cfg.curveFile); - curve.readCSV(in); - in.close(); - - byte[] external = curve.flatten(); - if (external == null) { - throw new IOException("Couldn't read the curve file correctly."); - } - return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external); - } else { - // Set default curve - /* This command was generally causing problems for simulating on jcardsim. - * Since there, .clearKey() resets all the keys values, even the domain. - * This might break some other stuff.. But should not. - */ - //commands.add(new Command.Clear(cardManager, keyPair)); - return null; - } - } - - - /** - * @param keyPair which keyPair/s to set the key params on - * @return a CommandAPDU setting params loaded on the keyPair/s - * @throws IOException if any of the key files cannot be found/opened - */ - public static Command prepareKey(CardMngr cardManager, EC_Store dataStore, ECTester.Config cfg, byte keyPair) throws IOException { - short params = EC_Consts.PARAMETERS_NONE; - byte[] data = null; - - if (cfg.key != null || cfg.namedKey != null) { - params |= EC_Consts.PARAMETERS_KEYPAIR; - EC_Params keypair; - if (cfg.key != null) { - keypair = new EC_Params(EC_Consts.PARAMETERS_KEYPAIR); - - FileInputStream in = new FileInputStream(cfg.key); - keypair.readCSV(in); - in.close(); - } else { - keypair = dataStore.getObject(EC_Keypair.class, cfg.namedKey); - } - - data = keypair.flatten(); - if (data == null) { - throw new IOException("Couldn't read the key file correctly."); - } - } - - if (cfg.publicKey != null || cfg.namedPublicKey != null) { - params |= EC_Consts.PARAMETER_W; - EC_Params pub; - if (cfg.publicKey != null) { - pub = new EC_Params(EC_Consts.PARAMETER_W); - - FileInputStream in = new FileInputStream(cfg.publicKey); - pub.readCSV(in); - in.close(); - } else { - pub = dataStore.getObject(EC_Key.Public.class, cfg.namedPublicKey); - if (pub == null) { - pub = dataStore.getObject(EC_Keypair.class, cfg.namedPublicKey); - } - } - - byte[] pubkey = pub.flatten(EC_Consts.PARAMETER_W); - if (pubkey == null) { - throw new IOException("Couldn't read the public key file correctly."); - } - data = pubkey; - } - if (cfg.privateKey != null || cfg.namedPrivateKey != null) { - params |= EC_Consts.PARAMETER_S; - EC_Params priv; - if (cfg.privateKey != null) { - priv = new EC_Params(EC_Consts.PARAMETER_S); - - FileInputStream in = new FileInputStream(cfg.privateKey); - priv.readCSV(in); - in.close(); - } else { - priv = dataStore.getObject(EC_Key.Public.class, cfg.namedPrivateKey); - if (priv == null) { - priv = dataStore.getObject(EC_Keypair.class, cfg.namedPrivateKey); - } - } - - byte[] privkey = priv.flatten(EC_Consts.PARAMETER_S); - if (privkey == null) { - throw new IOException("Couldn't read the private key file correctly."); - } - data = Util.concatenate(data, privkey); - } - return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, params, data); - } - - - /** - * - */ - public static class Allocate extends Command { - private byte keyPair; - private short keyLength; - private byte keyClass; - - /** - * Creates the INS_ALLOCATE instruction. - * - * @param cardManager cardManager to send APDU through - * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) - * @param keyLength key length to set - * @param keyClass key class to allocate - */ - protected Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) { - super(cardManager); - this.keyPair = keyPair; - this.keyLength = keyLength; - this.keyClass = keyClass; - - byte[] data = new byte[]{0, 0, keyClass}; - Util.setShort(data, 0, keyLength); - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data); - } - - @Override - public Response.Allocate send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Allocate(response, elapsed, keyPair, keyLength, keyClass); - } - } - - public static class AllocateKeyAgreement extends Command { - - private byte kaType; - - - /** - * Creates the INS_ALLOCATE_KA instruction. - * - * @param cardManager cardManager to send APDU through - * @param kaType which type of KeyAgreement to use - */ - protected AllocateKeyAgreement(CardMngr cardManager, byte kaType) { - super(cardManager); - this.kaType = kaType; - byte[] data = new byte[]{kaType}; - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_KA, 0x00, 0x00, data); - } - - @Override - public Response.AllocateKeyAgreement send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.AllocateKeyAgreement(response, elapsed, kaType); - } - } - - /** - * - */ - public static class Clear extends Command { - private byte keyPair; - - /** - * @param cardManager cardManager to send APDU through - * @param keyPair which keyPair clear, local/remote (KEYPAIR_* || ...) - */ - protected Clear(CardMngr cardManager, byte keyPair) { - super(cardManager); - this.keyPair = keyPair; - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CLEAR, keyPair, 0x00); - } - - @Override - public Response.Clear send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Clear(response, elapsed, keyPair); - } - } - - /** - * - */ - public static class Set extends Command { - private byte keyPair; - private byte curve; - private short params; - private byte[] external; - - /** - * Creates the INS_SET instruction. - * - * @param cardManager cardManager to send APDU through - * @param keyPair which keyPair to set params on, local/remote (KEYPAIR_* || ...) - * @param curve curve to set (EC_Consts.CURVE_*) - * @param params parameters to set (EC_Consts.PARAMETER_* | ...) - * @param external external curve data, can be null - */ - protected Set(CardMngr cardManager, byte keyPair, byte curve, short params, byte[] external) { - super(cardManager); - this.keyPair = keyPair; - this.curve = curve; - this.params = params; - this.external = external; - - int len = external != null ? 2 + external.length : 2; - byte[] data = new byte[len]; - Util.setShort(data, 0, params); - if (external != null) { - System.arraycopy(external, 0, data, 2, external.length); - } - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET, keyPair, curve, data); - } - - @Override - public Response.Set send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Set(response, elapsed, keyPair, curve, params); - } - } - - /** - * - */ - public static class Corrupt extends Command { - private byte keyPair; - private byte key; - private short params; - private byte corruption; - - /** - * @param cardManager cardManager to send APDU through - * @param keyPair which keyPair to corrupt, local/remote (KEYPAIR_* || ...) - * @param key key to corrupt (EC_Consts.KEY_* | ...) - * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) - * @param corruption corruption type (EC_Consts.CORRUPTION_*) - */ - protected Corrupt(CardMngr cardManager, byte keyPair, byte key, short params, byte corruption) { - super(cardManager); - this.keyPair = keyPair; - this.key = key; - this.params = params; - this.corruption = corruption; - - byte[] data = new byte[3]; - Util.setShort(data, 0, params); - data[2] = corruption; - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CORRUPT, keyPair, key, data); - } - - @Override - public Response.Corrupt send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Corrupt(response, elapsed, keyPair, key, params, corruption); - } - } - - /** - * - */ - public static class Generate extends Command { - private byte keyPair; - - /** - * Creates the INS_GENERATE instruction. - * - * @param cardManager cardManager to send APDU through - * @param keyPair which keyPair to generate, local/remote (KEYPAIR_* || ...) - */ - protected Generate(CardMngr cardManager, byte keyPair) { - super(cardManager); - this.keyPair = keyPair; - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_GENERATE, keyPair, 0); - } - - @Override - public Response.Generate send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Generate(response, elapsed, keyPair); - } - } - - /** - * - */ - public static class Export extends Command { - private byte keyPair; - private byte key; - private short params; - - /** - * Creates the INS_EXPORT instruction. - * - * @param cardManager cardManager to send APDU through - * @param keyPair keyPair to export from (KEYPAIR_* | ...) - * @param key key to export from (EC_Consts.KEY_* | ...) - * @param params params to export (EC_Consts.PARAMETER_* | ...) - */ - protected Export(CardMngr cardManager, byte keyPair, byte key, short params) { - super(cardManager); - this.keyPair = keyPair; - this.key = key; - this.params = params; - - byte[] data = new byte[2]; - Util.setShort(data, 0, params); - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_EXPORT, keyPair, key, data); - } - - @Override - public Response.Export send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Export(response, elapsed, keyPair, key, params); - } - } - - /** - * - */ - public static class ECDH extends Command { - private byte pubkey; - private byte privkey; - private byte export; - private short corruption; - private byte type; - - /** - * 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 corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) - * @param type ECDH algorithm type (EC_Consts.KA_* | ...) - */ - protected ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, short corruption, byte type) { - super(cardManager); - this.pubkey = pubkey; - this.privkey = privkey; - this.export = export; - this.corruption = corruption; - this.type = type; - - byte[] data = new byte[]{export, 0,0, type}; - Util.setShort(data, 1, corruption); - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); - } - - @Override - public Response.ECDH send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.ECDH(response, elapsed, pubkey, privkey, export, corruption, type); - } - } - - /** - * - */ - public static class ECDH_direct extends Command { - private byte privkey; - private byte export; - private short corruption; - private byte type; - private byte[] pubkey; - - /** - * 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 corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) - * @param type ECDH algorithm type (EC_Consts.KA_* | ...) - * @param pubkey pubkey data to do ECDH with. - */ - protected ECDH_direct(CardMngr cardManager, byte privkey, byte export, short corruption, byte type, byte[] pubkey) { - super(cardManager); - this.privkey = privkey; - this.export = export; - this.corruption = corruption; - this.type = type; - this.pubkey = pubkey; - - byte[] data = new byte[3 + pubkey.length]; - Util.setShort(data, 0, corruption); - data[2] = type; - System.arraycopy(pubkey, 0, data, 3, pubkey.length); - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH_DIRECT, privkey, export, data); - } - - @Override - public Response.ECDH send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.ECDH(response, elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, corruption, type); - } - } - - public static class ECDSA extends Command { - private byte keyPair; - private byte export; - private byte[] raw; - - /** - * Creates the INS_ECDSA instruction. - * - * @param cardManager cardManager to send APDU through - * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) - * @param export whether to export ECDSA signature - * @param raw data to sign, can be null, in which case random data is signed. - */ - protected ECDSA(CardMngr cardManager, byte keyPair, byte export, byte[] raw) { - super(cardManager); - this.keyPair = keyPair; - this.export = export; - this.raw = raw; - - int len = raw != null ? raw.length : 0; - byte[] data = new byte[2 + len]; - Util.setShort(data, 0, (short) len); - if (raw != null) { - System.arraycopy(raw, 0, data, 2, len); - } - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keyPair, export, data); - } - - @Override - public Response.ECDSA send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.ECDSA(response, elapsed, keyPair, export, raw); - } - } - - /** - * - */ - public static class Cleanup extends Command { - - /** - * @param cardManager cardManager to send APDU through - */ - protected Cleanup(CardMngr cardManager) { - super(cardManager); - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CLEANUP, 0, 0); - } - - @Override - public Response.Cleanup send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Cleanup(response, elapsed); - } - } - - /** - * - */ - public static class Support extends Command { - - /** - * @param cardManager cardManager to send APDU through - */ - protected Support(CardMngr cardManager) { - super(cardManager); - - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SUPPORT, 0, 0); - } - - @Override - public Response.Support send() throws CardException { - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(cmd); - elapsed += System.nanoTime(); - return new Response.Support(response, elapsed); - } - } -} - diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index ea2cbe4..a43c945 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -25,9 +25,12 @@ import cz.crcs.ectester.applet.ECTesterApplet; import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Category; import cz.crcs.ectester.reader.ec.EC_Data; import cz.crcs.ectester.reader.ec.EC_Params; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.TestSuite; import javacard.security.KeyPair; import org.apache.commons.cli.*; diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java deleted file mode 100644 index 3df956e..0000000 --- a/src/cz/crcs/ectester/reader/Response.java +++ /dev/null @@ -1,591 +0,0 @@ -package cz.crcs.ectester.reader; - -import cz.crcs.ectester.applet.ECTesterApplet; -import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.reader.ec.EC_Curve; -import javacard.framework.ISO7816; -import javacard.security.KeyPair; - -import javax.smartcardio.ResponseAPDU; -import java.util.List; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public abstract class Response { - - private ResponseAPDU resp; - private long time; - private short[] sws; - private int numSW = 0; - private byte[][] params; - //TODO replace params with EC_Data? - private boolean success = true; - - protected Response(ResponseAPDU response, long time) { - this.resp = response; - this.time = time; - } - - protected void parse(int numSW, int numParams) { - this.numSW = numSW; - this.sws = new short[numSW]; - - byte[] data = resp.getData(); - int offset = 0; - - //parse SWs in response - for (int i = 0; i < numSW; ++i) { - if (getLength() >= (offset + 2)) { - short sw = Util.getShort(data, offset); - offset += 2; - sws[i] = sw; - if (sw != ISO7816.SW_NO_ERROR) { - success = false; - } - } else { - success = false; - } - } - - if ((short) resp.getSW() != ISO7816.SW_NO_ERROR) - success = false; - - //try to parse numParams.. - params = new byte[numParams][]; - for (int i = 0; i < numParams; i++) { - if (data.length - offset < 2) { - success = false; - break; - } - short paramLength = Util.getShort(data, offset); - offset += 2; - if (data.length < offset + paramLength) { - success = false; - break; - } - params[i] = new byte[paramLength]; - System.arraycopy(data, offset, params[i], 0, paramLength); - offset += paramLength; - } - } - - public ResponseAPDU getAPDU() { - return resp; - } - - public long getDuration() { - return time; - } - - public short getNaturalSW() { - return (short) resp.getSW(); - } - - public short getSW(int index) { - return sws[index]; - } - - public int getNumSW() { - return numSW; - } - - public boolean hasParam(int index) { - return params.length >= index + 1 && params[index] != null; - } - - public int getParamLength(int index) { - return params[index].length; - } - - public byte[] getParam(int index) { - return params[index]; - } - - public byte[][] getParams() { - return params; - } - - public int getLength() { - return resp.getNr(); - } - - public boolean successful() { - return this.success; - } - - @Override - public abstract String toString(); - - public String toString(String inner) { - StringBuilder suffix = new StringBuilder(); - for (int j = 0; j < getNumSW(); ++j) { - short sw = getSW(j); - if (sw != 0) { - suffix.append(" ").append(Util.getSWString(sw)); - } - } - if (suffix.length() == 0) { - suffix.append(" [").append(Util.getSW(getNaturalSW())).append("]"); - } - return String.format("%-62s:%4d ms : %s", inner, time / 1000000, suffix); - } - - public static String toString(List responses) { - return toString(responses, null); - } - - public static String toString(List responses, String prefix) { - if (prefix != null) - prefix += " | "; - StringBuilder out = new StringBuilder(); - for (int i = 0; i < responses.size(); ++i) { - Response r = responses.get(i); - - if (prefix != null) - out.append(prefix); - - String message = r.toString(); - out.append(message); - if (i < responses.size() - 1) { - out.append("\n"); - } - } - return out.toString(); - } - - - /** - * - */ - public static class AllocateKeyAgreement extends Response { - byte kaType; - protected AllocateKeyAgreement(ResponseAPDU response, long time, byte kaType) { - super(response, time); - this.kaType = kaType; - - parse(2, 0); - } - - @Override - public String toString() { - return super.toString(String.format("Allocate KeyAgreement(%s) object", Util.getKATypeString(this.kaType))); - } - - } - - public static class Allocate extends Response { - - private byte keyPair; - private short keyLength; - private byte keyClass; - - protected Allocate(ResponseAPDU response, long time, byte keyPair, short keyLength, byte keyClass) { - super(response, time); - this.keyPair = keyPair; - this.keyLength = keyLength; - this.keyClass = keyClass; - - int pairs = 0; - if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; - if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; - parse(pairs, 0); - } - - @Override - public String toString() { - String field = keyClass == KeyPair.ALG_EC_FP ? "ALG_EC_FP" : "ALG_EC_F2M"; - String key; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - key = "both keypairs"; - } else { - key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return super.toString(String.format("Allocated %s %db %s", key, keyLength, field)); - } - } - - /** - * - */ - public static class Clear extends Response { - - private byte keyPair; - - protected Clear(ResponseAPDU response, long time, byte keyPair) { - super(response, time); - this.keyPair = keyPair; - - int pairs = 0; - if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; - if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; - parse(pairs, 0); - } - - @Override - public String toString() { - String key; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - key = "both keypairs"; - } else { - key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return super.toString(String.format("Cleared %s", key)); - } - } - - /** - * - */ - public static class Set extends Response { - - private byte keyPair; - private byte curve; - private short parameters; - - protected Set(ResponseAPDU response, long time, byte keyPair, byte curve, short parameters) { - super(response, time); - this.keyPair = keyPair; - this.curve = curve; - this.parameters = parameters; - - int pairs = 0; - if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; - if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; - - parse(pairs, 0); - } - - @Override - public String toString() { - String name; - switch (curve) { - case EC_Consts.CURVE_default: - name = "default"; - break; - case EC_Consts.CURVE_external: - name = "external"; - break; - default: - name = "custom"; - break; - } - String what = ""; - if (parameters == EC_Consts.PARAMETERS_DOMAIN_F2M || parameters == EC_Consts.PARAMETERS_DOMAIN_FP) { - what = "curve"; - } else if (parameters == EC_Consts.PARAMETER_W) { - what = "pubkey"; - } else if (parameters == EC_Consts.PARAMETER_S) { - what = "privkey"; - } else if (parameters == EC_Consts.PARAMETERS_KEYPAIR) { - what = "keypair"; - } - - String pair; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - pair = "both keypairs"; - } else { - pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return super.toString(String.format("Set %s %s parameters on %s", name, what, pair)); - } - - } - - /** - * - */ - public static class Corrupt extends Response { - - private byte keyPair; - private byte key; - private short params; - private byte corruption; - - protected Corrupt(ResponseAPDU response, long time, byte keyPair, byte key, short params, byte corruption) { - super(response, time); - this.keyPair = keyPair; - this.key = key; - this.params = params; - this.corruption = corruption; - - int pairs = 0; - if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; - if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; - - parse(pairs, 0); - } - - @Override - public String toString() { - String corrupt = Util.getCorruption(corruption); - - String pair; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - pair = "both keypairs"; - } else { - pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return super.toString(String.format("Corrupted params of %s, %s", pair, corrupt)); - } - } - - /** - * - */ - public static class Generate extends Response { - - private byte keyPair; - - protected Generate(ResponseAPDU response, long time, byte keyPair) { - super(response, time); - this.keyPair = keyPair; - - int generated = 0; - if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) generated++; - if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) generated++; - parse(generated, 0); - } - - @Override - public String toString() { - String key; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - key = "both keypairs"; - } else { - key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return super.toString(String.format("Generated %s", key)); - } - - } - - /** - * - */ - public static class Export extends Response { - - private byte keyPair; - private byte key; - private short parameters; - - protected Export(ResponseAPDU response, long time, byte keyPair, byte key, short parameters) { - super(response, time); - this.keyPair = keyPair; - this.key = key; - this.parameters = parameters; - - int exported = 0; - if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) exported++; - if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) exported++; - int keys = 0; - if ((key & EC_Consts.KEY_PUBLIC) != 0) keys++; - if ((key & EC_Consts.KEY_PRIVATE) != 0) keys++; - int paramCount = 0; - short mask = EC_Consts.PARAMETER_FP; - while (mask <= EC_Consts.PARAMETER_K) { - if ((mask & parameters) != 0) { - paramCount++; - } - mask = (short) (mask << 1); - } - int other = 0; - if ((key & EC_Consts.KEY_PUBLIC) != 0 && (parameters & EC_Consts.PARAMETER_W) != 0) other++; - if ((key & EC_Consts.KEY_PRIVATE) != 0 && (parameters & EC_Consts.PARAMETER_S) != 0) other++; - - parse(exported, exported * keys * paramCount + exported * other); - } - - private int getIndex(byte keyPair, short param) { - byte pair = ECTesterApplet.KEYPAIR_LOCAL; - int index = 0; - while (pair <= ECTesterApplet.KEYPAIR_REMOTE) { - short mask = EC_Consts.PARAMETER_FP; - while (mask <= EC_Consts.PARAMETER_S) { - if (pair == keyPair && param == mask) { - return index; - } - if ((parameters & mask) != 0 && (pair & keyPair) != 0) { - if (mask == EC_Consts.PARAMETER_W) { - if ((key & EC_Consts.KEY_PUBLIC) != 0) - index++; - } else if (mask == EC_Consts.PARAMETER_S) { - if ((key & EC_Consts.KEY_PRIVATE) != 0) - index++; - } else { - index++; - } - } - mask = (short) (mask << 1); - } - - pair = (byte) (pair << 1); - } - return -1; - } - - public boolean hasParameters(byte keyPair, short params) { - if ((keyPair & this.keyPair) == 0 || (params ^ parameters) != 0) { - return false; - } - short param = EC_Consts.PARAMETER_FP; - while (param <= EC_Consts.PARAMETER_S) { - short masked = (short) (param & params); - if (masked != 0 && !hasParameter(keyPair, masked)) { - return false; - } - param = (short) (param << 1); - } - return true; - } - - public boolean hasParameter(byte keyPair, short param) { - if ((keyPair & this.keyPair) == 0 || (parameters & param) == 0) { - return false; - } - int index = getIndex(keyPair, param); - return index != -1 && hasParam(index); - } - - public byte[] getParameter(byte keyPair, short param) { - return getParam(getIndex(keyPair, param)); - } - - @Override - public String toString() { - String source; - if (key == EC_Consts.KEY_BOTH) { - source = "both keys"; - } else { - source = ((key == EC_Consts.KEY_PUBLIC) ? "public" : "private") + " key"; - } - String pair; - if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - pair = "both keypairs"; - } else { - pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; - } - return super.toString(String.format("Exported params from %s of %s", source, pair)); - } - } - - /** - * - */ - public static class ECDH extends Response { - - private byte pubkey; - private byte privkey; - private byte export; - private short corruption; - private byte type; - - protected ECDH(ResponseAPDU response, long time, byte pubkey, byte privkey, byte export, short corruption, byte type) { - super(response, time); - this.pubkey = pubkey; - this.privkey = privkey; - this.export = export; - this.corruption = corruption; - this.type = type; - - parse(1, (export == ECTesterApplet.EXPORT_TRUE) ? 1 : 0); - } - - public boolean hasSecret() { - return hasParam(0); - } - - public byte[] getSecret() { - return getParam(0); - } - - public int secretLength() { - return getParamLength(0); - } - - @Override - public String toString() { - String algo = Util.getKA(type); - - String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; - String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; - - String validity; - if (corruption == EC_Consts.CORRUPTION_NONE) { - validity = "unchanged"; - } else { - validity = Util.getCorruption(corruption); - } - return super.toString(String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity)); - } - } - - /** - * - */ - public static class ECDSA extends Response { - - private byte keyPair; - private byte export; - private byte[] raw; - - protected ECDSA(ResponseAPDU response, long time, byte keyPair, byte export, byte[] raw) { - super(response, time); - this.keyPair = keyPair; - this.export = export; - this.raw = raw; - - parse(1, (export == ECTesterApplet.EXPORT_TRUE) ? 1 : 0); - } - - public boolean hasSignature() { - return hasParam(0); - } - - public byte[] getSignature() { - return getParam(0); - } - - @Override - public String toString() { - String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; - String data = raw == null ? "random" : "provided"; - return super.toString(String.format("ECDSA with %s keypair(%s data)", key, data)); - } - } - - /** - * - */ - public static class Cleanup extends Response { - - protected Cleanup(ResponseAPDU response, long time) { - super(response, time); - - parse(1, 0); - } - - @Override - public String toString() { - return super.toString("Requested JCSystem object deletion"); - } - - } - - /** - * - */ - public static class Support extends Response { - - protected Support(ResponseAPDU response, long time) { - super(response, time); - - parse(3, 0); - } - - @Override - public String toString() { - return super.toString("Support of ECDH, ECDHC, ECDSA"); - } - } -} diff --git a/src/cz/crcs/ectester/reader/Test.java b/src/cz/crcs/ectester/reader/Test.java deleted file mode 100644 index 157e360..0000000 --- a/src/cz/crcs/ectester/reader/Test.java +++ /dev/null @@ -1,82 +0,0 @@ -package cz.crcs.ectester.reader; - -import javax.smartcardio.CardException; -import java.util.function.BiFunction; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class Test { - private boolean hasRun = false; - private BiFunction callback; - private Result result; - private Result expected; - private Command command; - private Response response; - - public Test(Command command, Result expected) { - this.command = command; - this.expected = expected; - } - - public Test(Command command, Result expected, BiFunction callback) { - this(command, expected); - this.callback = callback; - } - - public Command getCommand() { - return command; - } - - public Response getResponse() { - return response; - } - - public Result getResult() { - if (!hasRun) { - return null; - } - return result; - } - - public Result getExpected() { - return expected; - } - - public boolean ok() { - return result == expected || expected == Result.ANY; - } - - public void run() throws CardException { - response = command.send(); - if (callback != null) { - result = callback.apply(command, response); - } else { - if (response.successful()) { - result = Result.SUCCESS; - } else { - result = Result.FAILURE; - } - } - hasRun = true; - } - - public boolean hasRun() { - return hasRun; - } - - @Override - public String toString() { - if (hasRun) { - return (ok() ? "OK " : "NOK") + " " + response.toString(); - } else { - return ""; - } - } - - public enum Result { - SUCCESS, - FAILURE, - ANY - } -} diff --git a/src/cz/crcs/ectester/reader/TestSuite.java b/src/cz/crcs/ectester/reader/TestSuite.java deleted file mode 100644 index 24b72a3..0000000 --- a/src/cz/crcs/ectester/reader/TestSuite.java +++ /dev/null @@ -1,314 +0,0 @@ -package cz.crcs.ectester.reader; - -import cz.crcs.ectester.applet.ECTesterApplet; -import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.data.EC_Store; -import cz.crcs.ectester.reader.ec.*; -import javacard.security.KeyPair; - -import javax.smartcardio.CardException; -import java.io.IOException; -import java.util.*; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public abstract class TestSuite { - - EC_Store dataStore; - ECTester.Config cfg; - DirtyLogger systemOut; - String name; - List tests = new LinkedList<>(); - - TestSuite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut, String name) { - this.dataStore = dataStore; - this.cfg = cfg; - this.systemOut = systemOut; - this.name = name; - } - - public List run(CardMngr cardManager) throws CardException, IOException { - for (Test t : tests) { - if (!t.hasRun()) { - t.run(); - systemOut.println(t.toString()); - } - } - return tests; - } - - public List getTests() { - return Collections.unmodifiableList(tests); - } - - public String getName() { - return name; - } - - /** - * @param cardManager cardManager to send APDU through - * @param generateExpected expected result of the Generate command - * @param ecdhExpected expected result of the ordinary ECDH command - * @param ecdsaExpected expected result of the ordinary ECDSA command - * @return tests to run - */ - List testCurve(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { - List tests = new LinkedList<>(); - - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); - - return tests; - } - - /** - * @param cardManager cardManager to send APDU through - * @param category category to test - * @param field field to test (KeyPair.ALG_EC_FP || KeyPair.ALG_EC_F2M) - * @param setExpected expected result of the Set (curve) command - * @param generateExpected expected result of the Generate command - * @param ecdhExpected expected result of the ordinary ECDH command - * @param ecdsaExpected expected result of the ordinary ECDSA command - * @return tests to run - */ - List testCategory(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { - List tests = new LinkedList<>(); - Map curves = dataStore.getObjects(EC_Curve.class, category); - if (curves == null) - return tests; - for (Map.Entry entry : curves.entrySet()) { - EC_Curve curve = entry.getValue(); - if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); - tests.addAll(testCurve(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - } - - return tests; - } - - public static class Default extends TestSuite { - - public Default(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "default"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - tests.add(new Test(new Command.Support(cardManager), Test.Result.ANY)); - if (cfg.namedCurve != null) { - if (cfg.primeField) { - tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - } - if (cfg.binaryField) { - tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - } - } else { - if (cfg.all) { - if (cfg.primeField) { - //iterate over prime curve sizes used: EC_Consts.FP_SIZES - for (short keyLength : EC_Consts.FP_SIZES) { - defaultTests(cardManager, keyLength, KeyPair.ALG_EC_FP); - } - } - if (cfg.binaryField) { - //iterate over binary curve sizes used: EC_Consts.F2M_SIZES - for (short keyLength : EC_Consts.F2M_SIZES) { - defaultTests(cardManager, keyLength, KeyPair.ALG_EC_F2M); - } - } - } else { - if (cfg.primeField) { - defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_FP); - } - - if (cfg.binaryField) { - defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_F2M); - } - } - } - return super.run(cardManager); - } - - private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); - if (curve != null) - tests.add(new Test(curve, Test.Result.SUCCESS)); - tests.addAll(testCurve(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - } - - public static class TestVectors extends TestSuite { - - public TestVectors(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "test"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. - * Do ECDH both ways, export and verify that the result is correct. - */ - Map results = dataStore.getObjects(EC_KAResult.class, "test"); - for (EC_KAResult result : results.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); - if (cfg.namedCurve != null && !(result.getCurve().startsWith(cfg.namedCurve) || result.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getBits() != cfg.bits && !cfg.all) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); - if (onekey == null) { - onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); - } - EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); - if (otherkey == null) { - otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); - } - if (onekey == null || otherkey == null) { - throw new IOException("Test vector keys couldn't be located."); - } - - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - //tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { - Response.ECDH dh = (Response.ECDH) response; - if (!dh.successful() || !dh.hasSecret()) - return Test.Result.FAILURE; - if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { - return Test.Result.FAILURE; - } - return Test.Result.SUCCESS; - })); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); - - } - return super.run(cardManager); - } - } - - public static class Composite extends TestSuite { - - public Composite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "composite"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - /* Do the default tests with the public keys set to provided smallorder keys - * over composite order curves. Essentially small subgroup attacks. - * These should fail, the curves aren't safe so that if the computation with - * a small order public key succeeds the private key modulo the public key order - * is revealed. - */ - Map keys = dataStore.getObjects(EC_Key.class, "composite"); - for (EC_Key key : keys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); - - //tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); - //tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); - - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - } - return super.run(cardManager); - } - } - - public static class Invalid extends TestSuite { - - public Invalid(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "invalid"); - } - - @Override - public List run(CardMngr cardManager) throws CardException, IOException { - /* Set original curves (secg/nist/brainpool). Generate local. - * Try ECDH with invalid public keys of increasing (or decreasing) order. - */ - Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); - Map> curves = new HashMap<>(); - for (EC_Key.Public key : pubkeys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getBits() != cfg.bits && !cfg.all) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - List keys = curves.getOrDefault(curve, new LinkedList<>()); - keys.add(key); - curves.putIfAbsent(curve, keys); - } - for (Map.Entry> e : curves.entrySet()) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); - for (EC_Key.Public pub : keys) { - // tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); - // tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); - } - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - - return super.run(cardManager); - } - } - - public static class Wrong extends TestSuite { - - public Wrong(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "wrong"); - } - - @Override - public List run(CardMngr cardManager) throws CardException, IOException { - /* Just do the default tests on the wrong curves. - * These should generally fail, the curves aren't curves. - */ - if (cfg.primeField) { - tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); - } - if (cfg.binaryField) { - tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); - } - return super.run(cardManager); - } - } -} diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java new file mode 100644 index 0000000..bab78c9 --- /dev/null +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -0,0 +1,592 @@ +package cz.crcs.ectester.reader.command; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.ec.EC_Curve; +import cz.crcs.ectester.reader.ec.EC_Key; +import cz.crcs.ectester.reader.ec.EC_Keypair; +import cz.crcs.ectester.reader.ec.EC_Params; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class Command { + CommandAPDU cmd; + CardMngr cardManager; + + Command(CardMngr cardManager) { + this.cardManager = cardManager; + } + + public CommandAPDU getAPDU() { + return cmd; + } + + public abstract Response send() throws CardException; + + public static List sendAll(List commands) throws CardException { + List result = new ArrayList<>(); + for (Command cmd : commands) { + result.add(cmd.send()); + } + return result; + } + + + /** + * @param keyPair which keyPair/s (local/remote) to set curve domain parameters on + * @param keyLength key length to choose + * @param keyClass key class to choose + * @return a Command to send in order to prepare the curve on the keypairs. + * @throws IOException if curve file cannot be found/opened + */ + public static Command prepareCurve(CardMngr cardManager, EC_Store dataStore, ECTester.Config cfg, byte keyPair, short keyLength, byte keyClass) throws IOException { + + if (cfg.customCurve) { + // Set custom curve (one of the SECG curves embedded applet-side) + short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; + return new Command.Set(cardManager, keyPair, EC_Consts.getCurve(keyLength, keyClass), domainParams, null); + } else if (cfg.namedCurve != null) { + // Set a named curve. + // parse cfg.namedCurve -> cat / id | cat | id + EC_Curve curve = dataStore.getObject(EC_Curve.class, cfg.namedCurve); + if (curve == null) { + throw new IOException("Curve could no be found."); + } + if (curve.getBits() != keyLength) { + throw new IOException("Curve bits mismatch: " + curve.getBits() + " vs " + keyLength + " entered."); + } + if (curve.getField() != keyClass) { + throw new IOException("Curve field mismatch."); + } + + byte[] external = curve.flatten(); + if (external == null) { + throw new IOException("Couldn't read named curve data."); + } + return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external); + } else if (cfg.curveFile != null) { + // Set curve loaded from a file + EC_Curve curve = new EC_Curve(null, keyLength, keyClass); + + FileInputStream in = new FileInputStream(cfg.curveFile); + curve.readCSV(in); + in.close(); + + byte[] external = curve.flatten(); + if (external == null) { + throw new IOException("Couldn't read the curve file correctly."); + } + return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external); + } else { + // Set default curve + /* This command was generally causing problems for simulating on jcardsim. + * Since there, .clearKey() resets all the keys values, even the domain. + * This might break some other stuff.. But should not. + */ + //commands.add(new Command.Clear(cardManager, keyPair)); + return null; + } + } + + + /** + * @param keyPair which keyPair/s to set the key params on + * @return a CommandAPDU setting params loaded on the keyPair/s + * @throws IOException if any of the key files cannot be found/opened + */ + public static Command prepareKey(CardMngr cardManager, EC_Store dataStore, ECTester.Config cfg, byte keyPair) throws IOException { + short params = EC_Consts.PARAMETERS_NONE; + byte[] data = null; + + if (cfg.key != null || cfg.namedKey != null) { + params |= EC_Consts.PARAMETERS_KEYPAIR; + EC_Params keypair; + if (cfg.key != null) { + keypair = new EC_Params(EC_Consts.PARAMETERS_KEYPAIR); + + FileInputStream in = new FileInputStream(cfg.key); + keypair.readCSV(in); + in.close(); + } else { + keypair = dataStore.getObject(EC_Keypair.class, cfg.namedKey); + } + + data = keypair.flatten(); + if (data == null) { + throw new IOException("Couldn't read the key file correctly."); + } + } + + if (cfg.publicKey != null || cfg.namedPublicKey != null) { + params |= EC_Consts.PARAMETER_W; + EC_Params pub; + if (cfg.publicKey != null) { + pub = new EC_Params(EC_Consts.PARAMETER_W); + + FileInputStream in = new FileInputStream(cfg.publicKey); + pub.readCSV(in); + in.close(); + } else { + pub = dataStore.getObject(EC_Key.Public.class, cfg.namedPublicKey); + if (pub == null) { + pub = dataStore.getObject(EC_Keypair.class, cfg.namedPublicKey); + } + } + + byte[] pubkey = pub.flatten(EC_Consts.PARAMETER_W); + if (pubkey == null) { + throw new IOException("Couldn't read the public key file correctly."); + } + data = pubkey; + } + if (cfg.privateKey != null || cfg.namedPrivateKey != null) { + params |= EC_Consts.PARAMETER_S; + EC_Params priv; + if (cfg.privateKey != null) { + priv = new EC_Params(EC_Consts.PARAMETER_S); + + FileInputStream in = new FileInputStream(cfg.privateKey); + priv.readCSV(in); + in.close(); + } else { + priv = dataStore.getObject(EC_Key.Public.class, cfg.namedPrivateKey); + if (priv == null) { + priv = dataStore.getObject(EC_Keypair.class, cfg.namedPrivateKey); + } + } + + byte[] privkey = priv.flatten(EC_Consts.PARAMETER_S); + if (privkey == null) { + throw new IOException("Couldn't read the private key file correctly."); + } + data = Util.concatenate(data, privkey); + } + return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, params, data); + } + + + /** + * + */ + public static class Allocate extends Command { + private byte keyPair; + private short keyLength; + private byte keyClass; + + /** + * Creates the INS_ALLOCATE instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) + * @param keyLength key length to set + * @param keyClass key class to allocate + */ + public Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) { + super(cardManager); + this.keyPair = keyPair; + this.keyLength = keyLength; + this.keyClass = keyClass; + + byte[] data = new byte[]{0, 0, keyClass}; + Util.setShort(data, 0, keyLength); + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data); + } + + @Override + public Response.Allocate send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Allocate(response, elapsed, keyPair, keyLength, keyClass); + } + } + + public static class AllocateKeyAgreement extends Command { + + private byte kaType; + + + /** + * Creates the INS_ALLOCATE_KA instruction. + * + * @param cardManager cardManager to send APDU through + * @param kaType which type of KeyAgreement to use + */ + public AllocateKeyAgreement(CardMngr cardManager, byte kaType) { + super(cardManager); + this.kaType = kaType; + byte[] data = new byte[]{kaType}; + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_KA, 0x00, 0x00, data); + } + + @Override + public Response.AllocateKeyAgreement send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.AllocateKeyAgreement(response, elapsed, kaType); + } + } + + /** + * + */ + public static class Clear extends Command { + private byte keyPair; + + /** + * @param cardManager cardManager to send APDU through + * @param keyPair which keyPair clear, local/remote (KEYPAIR_* || ...) + */ + public Clear(CardMngr cardManager, byte keyPair) { + super(cardManager); + this.keyPair = keyPair; + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CLEAR, keyPair, 0x00); + } + + @Override + public Response.Clear send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Clear(response, elapsed, keyPair); + } + } + + /** + * + */ + public static class Set extends Command { + private byte keyPair; + private byte curve; + private short params; + private byte[] external; + + /** + * Creates the INS_SET instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair which keyPair to set params on, local/remote (KEYPAIR_* || ...) + * @param curve curve to set (EC_Consts.CURVE_*) + * @param params parameters to set (EC_Consts.PARAMETER_* | ...) + * @param external external curve data, can be null + */ + public Set(CardMngr cardManager, byte keyPair, byte curve, short params, byte[] external) { + super(cardManager); + this.keyPair = keyPair; + this.curve = curve; + this.params = params; + this.external = external; + + int len = external != null ? 2 + external.length : 2; + byte[] data = new byte[len]; + Util.setShort(data, 0, params); + if (external != null) { + System.arraycopy(external, 0, data, 2, external.length); + } + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET, keyPair, curve, data); + } + + @Override + public Response.Set send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Set(response, elapsed, keyPair, curve, params); + } + } + + /** + * + */ + public static class Corrupt extends Command { + private byte keyPair; + private byte key; + private short params; + private byte corruption; + + /** + * @param cardManager cardManager to send APDU through + * @param keyPair which keyPair to corrupt, local/remote (KEYPAIR_* || ...) + * @param key key to corrupt (EC_Consts.KEY_* | ...) + * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) + * @param corruption corruption type (EC_Consts.CORRUPTION_*) + */ + public Corrupt(CardMngr cardManager, byte keyPair, byte key, short params, byte corruption) { + super(cardManager); + this.keyPair = keyPair; + this.key = key; + this.params = params; + this.corruption = corruption; + + byte[] data = new byte[3]; + Util.setShort(data, 0, params); + data[2] = corruption; + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CORRUPT, keyPair, key, data); + } + + @Override + public Response.Corrupt send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Corrupt(response, elapsed, keyPair, key, params, corruption); + } + } + + /** + * + */ + public static class Generate extends Command { + private byte keyPair; + + /** + * Creates the INS_GENERATE instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair which keyPair to generate, local/remote (KEYPAIR_* || ...) + */ + public Generate(CardMngr cardManager, byte keyPair) { + super(cardManager); + this.keyPair = keyPair; + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_GENERATE, keyPair, 0); + } + + @Override + public Response.Generate send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Generate(response, elapsed, keyPair); + } + } + + /** + * + */ + public static class Export extends Command { + private byte keyPair; + private byte key; + private short params; + + /** + * Creates the INS_EXPORT instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair keyPair to export from (KEYPAIR_* | ...) + * @param key key to export from (EC_Consts.KEY_* | ...) + * @param params params to export (EC_Consts.PARAMETER_* | ...) + */ + public Export(CardMngr cardManager, byte keyPair, byte key, short params) { + super(cardManager); + this.keyPair = keyPair; + this.key = key; + this.params = params; + + byte[] data = new byte[2]; + Util.setShort(data, 0, params); + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_EXPORT, keyPair, key, data); + } + + @Override + public Response.Export send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Export(response, elapsed, keyPair, key, params); + } + } + + /** + * + */ + public static class ECDH extends Command { + private byte pubkey; + private byte privkey; + private byte export; + private short corruption; + private byte type; + + /** + * 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 corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) + * @param type ECDH algorithm type (EC_Consts.KA_* | ...) + */ + public ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, short corruption, byte type) { + super(cardManager); + this.pubkey = pubkey; + this.privkey = privkey; + this.export = export; + this.corruption = corruption; + this.type = type; + + byte[] data = new byte[]{export, 0,0, type}; + Util.setShort(data, 1, corruption); + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); + } + + @Override + public Response.ECDH send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDH(response, elapsed, pubkey, privkey, export, corruption, type); + } + } + + /** + * + */ + public static class ECDH_direct extends Command { + private byte privkey; + private byte export; + private short corruption; + private byte type; + private byte[] pubkey; + + /** + * 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 corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) + * @param type ECDH algorithm type (EC_Consts.KA_* | ...) + * @param pubkey pubkey data to do ECDH with. + */ + public ECDH_direct(CardMngr cardManager, byte privkey, byte export, short corruption, byte type, byte[] pubkey) { + super(cardManager); + this.privkey = privkey; + this.export = export; + this.corruption = corruption; + this.type = type; + this.pubkey = pubkey; + + byte[] data = new byte[3 + pubkey.length]; + Util.setShort(data, 0, corruption); + data[2] = type; + System.arraycopy(pubkey, 0, data, 3, pubkey.length); + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH_DIRECT, privkey, export, data); + } + + @Override + public Response.ECDH send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDH(response, elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, corruption, type); + } + } + + public static class ECDSA extends Command { + private byte keyPair; + private byte export; + private byte[] raw; + + /** + * Creates the INS_ECDSA instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param export whether to export ECDSA signature + * @param raw data to sign, can be null, in which case random data is signed. + */ + public ECDSA(CardMngr cardManager, byte keyPair, byte export, byte[] raw) { + super(cardManager); + this.keyPair = keyPair; + this.export = export; + this.raw = raw; + + int len = raw != null ? raw.length : 0; + byte[] data = new byte[2 + len]; + Util.setShort(data, 0, (short) len); + if (raw != null) { + System.arraycopy(raw, 0, data, 2, len); + } + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keyPair, export, data); + } + + @Override + public Response.ECDSA send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDSA(response, elapsed, keyPair, export, raw); + } + } + + /** + * + */ + public static class Cleanup extends Command { + + /** + * @param cardManager cardManager to send APDU through + */ + public Cleanup(CardMngr cardManager) { + super(cardManager); + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CLEANUP, 0, 0); + } + + @Override + public Response.Cleanup send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Cleanup(response, elapsed); + } + } + + /** + * + */ + public static class Support extends Command { + + /** + * @param cardManager cardManager to send APDU through + */ + public Support(CardMngr cardManager) { + super(cardManager); + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SUPPORT, 0, 0); + } + + @Override + public Response.Support send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Support(response, elapsed); + } + } +} + diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java new file mode 100644 index 0000000..59b24fc --- /dev/null +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -0,0 +1,591 @@ +package cz.crcs.ectester.reader.response; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.reader.Util; +import javacard.framework.ISO7816; +import javacard.security.KeyPair; + +import javax.smartcardio.ResponseAPDU; +import java.util.List; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class Response { + + private ResponseAPDU resp; + private long time; + private short[] sws; + private int numSW = 0; + private byte[][] params; + //TODO replace params with EC_Data? + private boolean success = true; + + public Response(ResponseAPDU response, long time) { + this.resp = response; + this.time = time; + } + + public void parse(int numSW, int numParams) { + this.numSW = numSW; + this.sws = new short[numSW]; + + byte[] data = resp.getData(); + int offset = 0; + + //parse SWs in response + for (int i = 0; i < numSW; ++i) { + if (getLength() >= (offset + 2)) { + short sw = Util.getShort(data, offset); + offset += 2; + sws[i] = sw; + if (sw != ISO7816.SW_NO_ERROR) { + success = false; + } + } else { + success = false; + } + } + + if ((short) resp.getSW() != ISO7816.SW_NO_ERROR) + success = false; + + //try to parse numParams.. + params = new byte[numParams][]; + for (int i = 0; i < numParams; i++) { + if (data.length - offset < 2) { + success = false; + break; + } + short paramLength = Util.getShort(data, offset); + offset += 2; + if (data.length < offset + paramLength) { + success = false; + break; + } + params[i] = new byte[paramLength]; + System.arraycopy(data, offset, params[i], 0, paramLength); + offset += paramLength; + } + } + + public ResponseAPDU getAPDU() { + return resp; + } + + public long getDuration() { + return time; + } + + public short getNaturalSW() { + return (short) resp.getSW(); + } + + public short getSW(int index) { + return sws[index]; + } + + public int getNumSW() { + return numSW; + } + + public boolean hasParam(int index) { + return params.length >= index + 1 && params[index] != null; + } + + public int getParamLength(int index) { + return params[index].length; + } + + public byte[] getParam(int index) { + return params[index]; + } + + public byte[][] getParams() { + return params; + } + + public int getLength() { + return resp.getNr(); + } + + public boolean successful() { + return this.success; + } + + @Override + public abstract String toString(); + + public String toString(String inner) { + StringBuilder suffix = new StringBuilder(); + for (int j = 0; j < getNumSW(); ++j) { + short sw = getSW(j); + if (sw != 0) { + suffix.append(" ").append(Util.getSWString(sw)); + } + } + if (suffix.length() == 0) { + suffix.append(" [").append(Util.getSW(getNaturalSW())).append("]"); + } + return String.format("%-62s:%4d ms : %s", inner, time / 1000000, suffix); + } + + public static String toString(List responses) { + return toString(responses, null); + } + + public static String toString(List responses, String prefix) { + if (prefix != null) + prefix += " | "; + StringBuilder out = new StringBuilder(); + for (int i = 0; i < responses.size(); ++i) { + Response r = responses.get(i); + + if (prefix != null) + out.append(prefix); + + String message = r.toString(); + out.append(message); + if (i < responses.size() - 1) { + out.append("\n"); + } + } + return out.toString(); + } + + + /** + * + */ + public static class AllocateKeyAgreement extends Response { + byte kaType; + public AllocateKeyAgreement(ResponseAPDU response, long time, byte kaType) { + super(response, time); + this.kaType = kaType; + + parse(2, 0); + } + + @Override + public String toString() { + return super.toString(String.format("Allocate KeyAgreement(%s) object", Util.getKATypeString(this.kaType))); + } + + } + + public static class Allocate extends Response { + + private byte keyPair; + private short keyLength; + private byte keyClass; + + public Allocate(ResponseAPDU response, long time, byte keyPair, short keyLength, byte keyClass) { + super(response, time); + this.keyPair = keyPair; + this.keyLength = keyLength; + this.keyClass = keyClass; + + int pairs = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; + parse(pairs, 0); + } + + @Override + public String toString() { + String field = keyClass == KeyPair.ALG_EC_FP ? "ALG_EC_FP" : "ALG_EC_F2M"; + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return super.toString(String.format("Allocated %s %db %s", key, keyLength, field)); + } + } + + /** + * + */ + public static class Clear extends Response { + + private byte keyPair; + + public Clear(ResponseAPDU response, long time, byte keyPair) { + super(response, time); + this.keyPair = keyPair; + + int pairs = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; + parse(pairs, 0); + } + + @Override + public String toString() { + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return super.toString(String.format("Cleared %s", key)); + } + } + + /** + * + */ + public static class Set extends Response { + + private byte keyPair; + private byte curve; + private short parameters; + + public Set(ResponseAPDU response, long time, byte keyPair, byte curve, short parameters) { + super(response, time); + this.keyPair = keyPair; + this.curve = curve; + this.parameters = parameters; + + int pairs = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; + + parse(pairs, 0); + } + + @Override + public String toString() { + String name; + switch (curve) { + case EC_Consts.CURVE_default: + name = "default"; + break; + case EC_Consts.CURVE_external: + name = "external"; + break; + default: + name = "custom"; + break; + } + String what = ""; + if (parameters == EC_Consts.PARAMETERS_DOMAIN_F2M || parameters == EC_Consts.PARAMETERS_DOMAIN_FP) { + what = "curve"; + } else if (parameters == EC_Consts.PARAMETER_W) { + what = "pubkey"; + } else if (parameters == EC_Consts.PARAMETER_S) { + what = "privkey"; + } else if (parameters == EC_Consts.PARAMETERS_KEYPAIR) { + what = "keypair"; + } + + String pair; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + pair = "both keypairs"; + } else { + pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return super.toString(String.format("Set %s %s parameters on %s", name, what, pair)); + } + + } + + /** + * + */ + public static class Corrupt extends Response { + + private byte keyPair; + private byte key; + private short params; + private byte corruption; + + public Corrupt(ResponseAPDU response, long time, byte keyPair, byte key, short params, byte corruption) { + super(response, time); + this.keyPair = keyPair; + this.key = key; + this.params = params; + this.corruption = corruption; + + int pairs = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; + + parse(pairs, 0); + } + + @Override + public String toString() { + String corrupt = Util.getCorruption(corruption); + + String pair; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + pair = "both keypairs"; + } else { + pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return super.toString(String.format("Corrupted params of %s, %s", pair, corrupt)); + } + } + + /** + * + */ + public static class Generate extends Response { + + private byte keyPair; + + public Generate(ResponseAPDU response, long time, byte keyPair) { + super(response, time); + this.keyPair = keyPair; + + int generated = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) generated++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) generated++; + parse(generated, 0); + } + + @Override + public String toString() { + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return super.toString(String.format("Generated %s", key)); + } + + } + + /** + * + */ + public static class Export extends Response { + + private byte keyPair; + private byte key; + private short parameters; + + public Export(ResponseAPDU response, long time, byte keyPair, byte key, short parameters) { + super(response, time); + this.keyPair = keyPair; + this.key = key; + this.parameters = parameters; + + int exported = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) exported++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) exported++; + int keys = 0; + if ((key & EC_Consts.KEY_PUBLIC) != 0) keys++; + if ((key & EC_Consts.KEY_PRIVATE) != 0) keys++; + int paramCount = 0; + short mask = EC_Consts.PARAMETER_FP; + while (mask <= EC_Consts.PARAMETER_K) { + if ((mask & parameters) != 0) { + paramCount++; + } + mask = (short) (mask << 1); + } + int other = 0; + if ((key & EC_Consts.KEY_PUBLIC) != 0 && (parameters & EC_Consts.PARAMETER_W) != 0) other++; + if ((key & EC_Consts.KEY_PRIVATE) != 0 && (parameters & EC_Consts.PARAMETER_S) != 0) other++; + + parse(exported, exported * keys * paramCount + exported * other); + } + + private int getIndex(byte keyPair, short param) { + byte pair = ECTesterApplet.KEYPAIR_LOCAL; + int index = 0; + while (pair <= ECTesterApplet.KEYPAIR_REMOTE) { + short mask = EC_Consts.PARAMETER_FP; + while (mask <= EC_Consts.PARAMETER_S) { + if (pair == keyPair && param == mask) { + return index; + } + if ((parameters & mask) != 0 && (pair & keyPair) != 0) { + if (mask == EC_Consts.PARAMETER_W) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) + index++; + } else if (mask == EC_Consts.PARAMETER_S) { + if ((key & EC_Consts.KEY_PRIVATE) != 0) + index++; + } else { + index++; + } + } + mask = (short) (mask << 1); + } + + pair = (byte) (pair << 1); + } + return -1; + } + + public boolean hasParameters(byte keyPair, short params) { + if ((keyPair & this.keyPair) == 0 || (params ^ parameters) != 0) { + return false; + } + short param = EC_Consts.PARAMETER_FP; + while (param <= EC_Consts.PARAMETER_S) { + short masked = (short) (param & params); + if (masked != 0 && !hasParameter(keyPair, masked)) { + return false; + } + param = (short) (param << 1); + } + return true; + } + + public boolean hasParameter(byte keyPair, short param) { + if ((keyPair & this.keyPair) == 0 || (parameters & param) == 0) { + return false; + } + int index = getIndex(keyPair, param); + return index != -1 && hasParam(index); + } + + public byte[] getParameter(byte keyPair, short param) { + return getParam(getIndex(keyPair, param)); + } + + @Override + public String toString() { + String source; + if (key == EC_Consts.KEY_BOTH) { + source = "both keys"; + } else { + source = ((key == EC_Consts.KEY_PUBLIC) ? "public" : "private") + " key"; + } + String pair; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + pair = "both keypairs"; + } else { + pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return super.toString(String.format("Exported params from %s of %s", source, pair)); + } + } + + /** + * + */ + public static class ECDH extends Response { + + private byte pubkey; + private byte privkey; + private byte export; + private short corruption; + private byte type; + + public ECDH(ResponseAPDU response, long time, byte pubkey, byte privkey, byte export, short corruption, byte type) { + super(response, time); + this.pubkey = pubkey; + this.privkey = privkey; + this.export = export; + this.corruption = corruption; + this.type = type; + + parse(1, (export == ECTesterApplet.EXPORT_TRUE) ? 1 : 0); + } + + public boolean hasSecret() { + return hasParam(0); + } + + public byte[] getSecret() { + return getParam(0); + } + + public int secretLength() { + return getParamLength(0); + } + + @Override + public String toString() { + String algo = Util.getKA(type); + + String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + + String validity; + if (corruption == EC_Consts.CORRUPTION_NONE) { + validity = "unchanged"; + } else { + validity = Util.getCorruption(corruption); + } + return super.toString(String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity)); + } + } + + /** + * + */ + public static class ECDSA extends Response { + + private byte keyPair; + private byte export; + private byte[] raw; + + public ECDSA(ResponseAPDU response, long time, byte keyPair, byte export, byte[] raw) { + super(response, time); + this.keyPair = keyPair; + this.export = export; + this.raw = raw; + + parse(1, (export == ECTesterApplet.EXPORT_TRUE) ? 1 : 0); + } + + public boolean hasSignature() { + return hasParam(0); + } + + public byte[] getSignature() { + return getParam(0); + } + + @Override + public String toString() { + String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String data = raw == null ? "random" : "provided"; + return super.toString(String.format("ECDSA with %s keypair(%s data)", key, data)); + } + } + + /** + * + */ + public static class Cleanup extends Response { + + public Cleanup(ResponseAPDU response, long time) { + super(response, time); + + parse(1, 0); + } + + @Override + public String toString() { + return super.toString("Requested JCSystem object deletion"); + } + + } + + /** + * + */ + public static class Support extends Response { + + public Support(ResponseAPDU response, long time) { + super(response, time); + + parse(3, 0); + } + + @Override + public String toString() { + return super.toString("Support of ECDH, ECDHC, ECDSA"); + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java new file mode 100644 index 0000000..e22e0a4 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -0,0 +1,85 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.response.Response; + +import javax.smartcardio.CardException; +import java.util.function.BiFunction; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class Test { + private boolean hasRun = false; + private BiFunction callback; + private Result result; + private Result expected; + private Command command; + private Response response; + + public Test(Command command, Result expected) { + this.command = command; + this.expected = expected; + } + + public Test(Command command, Result expected, BiFunction callback) { + this(command, expected); + this.callback = callback; + } + + public Command getCommand() { + return command; + } + + public Response getResponse() { + return response; + } + + public Result getResult() { + if (!hasRun) { + return null; + } + return result; + } + + public Result getExpected() { + return expected; + } + + public boolean ok() { + return result == expected || expected == Result.ANY; + } + + public void run() throws CardException { + response = command.send(); + if (callback != null) { + result = callback.apply(command, response); + } else { + if (response.successful()) { + result = Result.SUCCESS; + } else { + result = Result.FAILURE; + } + } + hasRun = true; + } + + public boolean hasRun() { + return hasRun; + } + + @Override + public String toString() { + if (hasRun) { + return (ok() ? "OK " : "NOK") + " " + response.toString(); + } else { + return ""; + } + } + + public enum Result { + SUCCESS, + FAILURE, + ANY + } +} diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java new file mode 100644 index 0000000..2f52f38 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -0,0 +1,320 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.DirtyLogger; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.ec.*; +import cz.crcs.ectester.reader.response.Response; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.*; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class TestSuite { + + EC_Store dataStore; + ECTester.Config cfg; + DirtyLogger systemOut; + String name; + List tests = new LinkedList<>(); + + TestSuite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut, String name) { + this.dataStore = dataStore; + this.cfg = cfg; + this.systemOut = systemOut; + this.name = name; + } + + public List run(CardMngr cardManager) throws CardException, IOException { + for (Test t : tests) { + if (!t.hasRun()) { + t.run(); + systemOut.println(t.toString()); + } + } + return tests; + } + + public List getTests() { + return Collections.unmodifiableList(tests); + } + + public String getName() { + return name; + } + + /** + * @param cardManager cardManager to send APDU through + * @param generateExpected expected result of the Generate command + * @param ecdhExpected expected result of the ordinary ECDH command + * @param ecdsaExpected expected result of the ordinary ECDSA command + * @return tests to run + */ + List testCurve(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List tests = new LinkedList<>(); + + tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); + + return tests; + } + + /** + * @param cardManager cardManager to send APDU through + * @param category category to test + * @param field field to test (KeyPair.ALG_EC_FP || KeyPair.ALG_EC_F2M) + * @param setExpected expected result of the Set (curve) command + * @param generateExpected expected result of the Generate command + * @param ecdhExpected expected result of the ordinary ECDH command + * @param ecdsaExpected expected result of the ordinary ECDSA command + * @return tests to run + */ + List testCategory(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List tests = new LinkedList<>(); + Map curves = dataStore.getObjects(EC_Curve.class, category); + if (curves == null) + return tests; + for (Map.Entry entry : curves.entrySet()) { + EC_Curve curve = entry.getValue(); + if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); + tests.addAll(testCurve(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + + return tests; + } + + public static class Default extends TestSuite { + + public Default(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "default"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + tests.add(new Test(new Command.Support(cardManager), Test.Result.ANY)); + if (cfg.namedCurve != null) { + if (cfg.primeField) { + tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + } + if (cfg.binaryField) { + tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + } + } else { + if (cfg.all) { + if (cfg.primeField) { + //iterate over prime curve sizes used: EC_Consts.FP_SIZES + for (short keyLength : EC_Consts.FP_SIZES) { + defaultTests(cardManager, keyLength, KeyPair.ALG_EC_FP); + } + } + if (cfg.binaryField) { + //iterate over binary curve sizes used: EC_Consts.F2M_SIZES + for (short keyLength : EC_Consts.F2M_SIZES) { + defaultTests(cardManager, keyLength, KeyPair.ALG_EC_F2M); + } + } + } else { + if (cfg.primeField) { + defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_FP); + } + + if (cfg.binaryField) { + defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_F2M); + } + } + } + return super.run(cardManager); + } + + private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); + Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); + if (curve != null) + tests.add(new Test(curve, Test.Result.SUCCESS)); + tests.addAll(testCurve(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + + public static class TestVectors extends TestSuite { + + public TestVectors(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "test"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. + * Do ECDH both ways, export and verify that the result is correct. + */ + Map results = dataStore.getObjects(EC_KAResult.class, "test"); + for (EC_KAResult result : results.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); + if (cfg.namedCurve != null && !(result.getCurve().startsWith(cfg.namedCurve) || result.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); + if (onekey == null) { + onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); + } + EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); + if (otherkey == null) { + otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); + } + if (onekey == null || otherkey == null) { + throw new IOException("Test vector keys couldn't be located."); + } + + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + //tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + Response.ECDH dh = (Response.ECDH) response; + if (!dh.successful() || !dh.hasSecret()) + return Test.Result.FAILURE; + if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { + return Test.Result.FAILURE; + } + return Test.Result.SUCCESS; + })); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + + } + return super.run(cardManager); + } + } + + public static class Composite extends TestSuite { + + public Composite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "composite"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + /* Do the default tests with the public keys set to provided smallorder keys + * over composite order curves. Essentially small subgroup attacks. + * These should fail, the curves aren't safe so that if the computation with + * a small order public key succeeds the private key modulo the public key order + * is revealed. + */ + Map keys = dataStore.getObjects(EC_Key.class, "composite"); + for (EC_Key key : keys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + if ((curve.getBits() == cfg.bits || cfg.all)) { + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); + tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + + //tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); + //tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); + + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + return super.run(cardManager); + } + } + + public static class Invalid extends TestSuite { + + public Invalid(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "invalid"); + } + + @Override + public List run(CardMngr cardManager) throws CardException, IOException { + /* Set original curves (secg/nist/brainpool). Generate local. + * Try ECDH with invalid public keys of increasing (or decreasing) order. + */ + Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + Map> curves = new HashMap<>(); + for (EC_Key.Public key : pubkeys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + List keys = curves.getOrDefault(curve, new LinkedList<>()); + keys.add(key); + curves.putIfAbsent(curve, keys); + } + for (Map.Entry> e : curves.entrySet()) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + for (EC_Key.Public pub : keys) { + // tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); + // tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); + tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); + } + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + + return super.run(cardManager); + } + } + + public static class Wrong extends TestSuite { + + public Wrong(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { + super(dataStore, cfg, systemOut, "wrong"); + } + + @Override + public List run(CardMngr cardManager) throws CardException, IOException { + /* Just do the default tests on the wrong curves. + * These should generally fail, the curves aren't curves. + */ + if (cfg.primeField) { + tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + } + if (cfg.binaryField) { + tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + } + return super.run(cardManager); + } + } +} -- cgit v1.2.3-70-g09d2 From 88f829e238097343a044f437c2d4cfeb8b6cfdff Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 15 Oct 2017 00:01:42 +0200 Subject: Abstract out Test and move its simple implementation to Test.Simple. - Also create a Test.Compound nested static class that can combine multiple Tests and their Results, and has a single Result. --- src/cz/crcs/ectester/reader/test/Test.java | 175 +++++++++++++++++------- src/cz/crcs/ectester/reader/test/TestSuite.java | 72 +++++----- 2 files changed, 159 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index e22e0a4..cd0cf49 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -5,35 +5,16 @@ import cz.crcs.ectester.reader.response.Response; import javax.smartcardio.CardException; import java.util.function.BiFunction; +import java.util.function.Function; /** + * An abstract test that can be run and has a Result. + * * @author Jan Jancar johny@neuromancer.sk */ -public class Test { - private boolean hasRun = false; - private BiFunction callback; - private Result result; - private Result expected; - private Command command; - private Response response; - - public Test(Command command, Result expected) { - this.command = command; - this.expected = expected; - } - - public Test(Command command, Result expected, BiFunction callback) { - this(command, expected); - this.callback = callback; - } - - public Command getCommand() { - return command; - } - - public Response getResponse() { - return response; - } +public abstract class Test { + boolean hasRun = false; + Result result; public Result getResult() { if (!hasRun) { @@ -42,44 +23,134 @@ public class Test { return result; } - public Result getExpected() { - return expected; + public boolean hasRun() { + return hasRun; } - public boolean ok() { - return result == expected || expected == Result.ANY; + public abstract boolean ok(); + + public abstract void run() throws CardException; + + /** + * A result of a Test. + */ + public enum Result { + SUCCESS, + FAILURE, + ANY } - public void run() throws CardException { - response = command.send(); - if (callback != null) { - result = callback.apply(command, response); - } else { - if (response.successful()) { - result = Result.SUCCESS; + /** + * A simple test that runs one Command to get and evaluate one Response + * to get a Result and compare it with the expected one. + */ + public static class Simple extends Test { + private BiFunction callback; + private Result expected; + private Command command; + private Response response; + + public Simple(Command command, Result expected) { + this.command = command; + this.expected = expected; + } + + public Simple(Command command, Result expected, BiFunction callback) { + this(command, expected); + this.callback = callback; + } + + public Command getCommand() { + return command; + } + + public Response getResponse() { + return response; + } + + public Result getExpected() { + return expected; + } + + @Override + public boolean ok() { + return result == expected || expected == Result.ANY; + } + + @Override + public void run() throws CardException { + response = command.send(); + if (callback != null) { + result = callback.apply(command, response); } else { - result = Result.FAILURE; + if (response.successful()) { + result = Result.SUCCESS; + } else { + result = Result.FAILURE; + } } + hasRun = true; } - hasRun = true; - } - public boolean hasRun() { - return hasRun; + @Override + public String toString() { + if (hasRun) { + return (ok() ? "OK " : "NOK") + " " + response.toString(); + } else { + return ""; + } + } } - @Override - public String toString() { - if (hasRun) { - return (ok() ? "OK " : "NOK") + " " + response.toString(); - } else { - return ""; + /** + * A compound test that runs many Tests and has a Result dependent on all/some of their Results. + */ + public static class Compound extends Test { + private Function callback; + private Test[] tests; + + private Compound(Function callback, Test... tests) { + this.callback = callback; + this.tests = tests; } - } - public enum Result { - SUCCESS, - FAILURE, - ANY + public Compound function(Function callback, Test... tests) { + return new Compound(callback, tests); + } + + public Compound all(Result what, Test... all) { + return new Compound((tests) -> { + for (Test test : tests) { + if (test.getResult() != what) { + return Result.FAILURE; + } + } + return Result.SUCCESS; + }, all); + } + + public Compound any(Result what, Test... any) { + return new Compound((tests) -> { + for (Test test : tests) { + if (test.getResult() == what) { + return Result.SUCCESS; + } + } + return Result.FAILURE; + }, any); + } + + @Override + public boolean ok() { + return result == Result.SUCCESS; + } + + @Override + public void run() throws CardException { + for (Test test: tests) { + test.run(); + } + result = callback.apply(tests); + } } } diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 2f52f38..7ce9e0f 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -62,14 +62,14 @@ public abstract class TestSuite { List testCurve(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { List tests = new LinkedList<>(); - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return tests; } @@ -92,10 +92,10 @@ public abstract class TestSuite { for (Map.Entry entry : curves.entrySet()) { EC_Curve curve = entry.getValue(); if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); tests.addAll(testCurve(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } @@ -110,7 +110,7 @@ public abstract class TestSuite { @Override public List run(CardMngr cardManager) throws IOException, CardException { - tests.add(new Test(new Command.Support(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); if (cfg.namedCurve != null) { if (cfg.primeField) { tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); @@ -146,12 +146,12 @@ public abstract class TestSuite { } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) - tests.add(new Test(curve, Test.Result.SUCCESS)); + tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); tests.addAll(testCurve(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } @@ -190,12 +190,12 @@ public abstract class TestSuite { throw new IOException("Test vector keys couldn't be located."); } - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - //tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { Response.ECDH dh = (Response.ECDH) response; if (!dh.successful() || !dh.hasSecret()) return Test.Result.FAILURE; @@ -204,7 +204,7 @@ public abstract class TestSuite { } return Test.Result.SUCCESS; })); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } return super.run(cardManager); @@ -235,15 +235,15 @@ public abstract class TestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); - //tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); - //tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); + //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); + //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } return super.run(cardManager); @@ -282,15 +282,15 @@ public abstract class TestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); for (EC_Key.Public pub : keys) { - // tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); - // tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); - tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); + // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); + // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); } - tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } return super.run(cardManager); -- cgit v1.2.3-70-g09d2 From 114c3378e323b954bfd8c0470e489c9615978d58 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 14 Oct 2017 01:14:07 +0200 Subject: Refactor response and test outputing into separate writers. This is done to provide multiple output formats, one which logs tests to console in simple human readable format and others. --- src/cz/crcs/ectester/reader/DirtyLogger.java | 56 -------------- src/cz/crcs/ectester/reader/ECTester.java | 83 ++++++++++++++------- .../ectester/reader/output/HTMLOutputWriter.java | 29 ++++++++ .../crcs/ectester/reader/output/OutputLogger.java | 60 +++++++++++++++ .../crcs/ectester/reader/output/OutputWriter.java | 14 ++++ .../ectester/reader/output/TeeOutputStream.java | 36 +++++++++ .../ectester/reader/output/TextOutputWriter.java | 72 ++++++++++++++++++ .../ectester/reader/output/XMLOutputWriter.java | 29 ++++++++ src/cz/crcs/ectester/reader/response/Response.java | 85 ++++++---------------- src/cz/crcs/ectester/reader/test/Test.java | 21 ++++-- src/cz/crcs/ectester/reader/test/TestSuite.java | 33 +++++---- 11 files changed, 352 insertions(+), 166 deletions(-) delete mode 100644 src/cz/crcs/ectester/reader/DirtyLogger.java create mode 100644 src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/OutputLogger.java create mode 100644 src/cz/crcs/ectester/reader/output/OutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/TeeOutputStream.java create mode 100644 src/cz/crcs/ectester/reader/output/TextOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/XMLOutputWriter.java (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/DirtyLogger.java b/src/cz/crcs/ectester/reader/DirtyLogger.java deleted file mode 100644 index 7a2c70d..0000000 --- a/src/cz/crcs/ectester/reader/DirtyLogger.java +++ /dev/null @@ -1,56 +0,0 @@ -package cz.crcs.ectester.reader; - -import java.io.FileWriter; -import java.io.IOException; -import java.io.OutputStream; - -/** - * @author Petr Svenda petr@svenda.com - * @author Jan Jancar johny@neuromancer.sk - */ -public class DirtyLogger { - FileWriter log; - boolean systemOut; - - public DirtyLogger(String filePath) throws IOException { - this(filePath, true); - } - - public DirtyLogger(String filePath, boolean systemOut) throws IOException { - if (filePath != null) - this.log = new FileWriter(filePath); - this.systemOut = systemOut; - } - - public void println() { - print("\n"); - } - - public void println(String logLine) { - logLine += "\n"; - print(logLine); - } - - public void print(String logLine) { - if (systemOut) { - System.out.print(logLine); - } - if (log != null) { - try { - log.write(logLine); - } catch (IOException ignored) { - } - } - } - - void flush() { - try { - if (log != null) log.flush(); - } catch (IOException ignored) { - } - } - - void close() throws IOException { - if (log != null) log.close(); - } -} diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index a43c945..c0c282c 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -22,13 +22,13 @@ package cz.crcs.ectester.reader; import cz.crcs.ectester.applet.ECTesterApplet; -import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Category; import cz.crcs.ectester.reader.ec.EC_Data; import cz.crcs.ectester.reader.ec.EC_Params; +import cz.crcs.ectester.reader.output.*; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.TestSuite; import javacard.security.KeyPair; @@ -39,6 +39,8 @@ import java.io.*; import java.nio.file.Files; import java.util.*; +import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + /** * Reader part of ECTester, a tool for testing Elliptic curve support on javacards. * @@ -48,7 +50,8 @@ import java.util.*; public class ECTester { private CardMngr cardManager; - private DirtyLogger systemOutLogger; + private OutputLogger logger; + private OutputWriter writer; private EC_Store dataStore; private Config cfg; @@ -101,7 +104,22 @@ public class ECTester { cardManager.send(SELECT_ECTESTERAPPLET); } - systemOutLogger = new DirtyLogger(cfg.log, true); + logger = new OutputLogger(true, cfg.log); + if (cfg.format == null) { + writer = new TextOutputWriter(logger.getPrintStream()); + } else { + switch (cfg.format) { + case "text": + writer = new TextOutputWriter(logger.getPrintStream()); + break; + case "xml": + writer = new XMLOutputWriter(); + break; + case "html": + writer = new HTMLOutputWriter(); + break; + } + } //do action if (cli.hasOption("export")) { @@ -118,7 +136,7 @@ public class ECTester { //disconnect cardManager.disconnectFromCard(); - systemOutLogger.close(); + logger.close(); } catch (MissingOptionException moex) { System.err.println("Missing required options, one of:"); @@ -157,11 +175,11 @@ public class ECTester { } catch (ParseException | IOException ex) { System.err.println(ex.getMessage()); } catch (CardException ex) { - if (systemOutLogger != null) - systemOutLogger.println(ex.getMessage()); + if (logger != null) + logger.println(ex.getMessage()); } finally { - if (systemOutLogger != null) - systemOutLogger.flush(); + if (logger != null) + logger.flush(); } } @@ -223,7 +241,7 @@ public class ECTester { actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do ECDH, [count] times.").hasArg().argName("count").optionalArg(true).build()); actions.addOption(Option.builder("dhc").longOpt("ecdhc").desc("Do ECDHC, [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()); - + opts.addOptionGroup(actions); OptionGroup size = new OptionGroup(); @@ -259,6 +277,7 @@ public class ECTester { opts.addOption(Option.builder("o").longOpt("output").desc("Output into file .").hasArg().argName("output_file").build()); opts.addOption(Option.builder("l").longOpt("log").desc("Log output into file [log_file].").hasArg().argName("log_file").optionalArg(true).build()); opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build()); + opts.addOption(Option.builder().longOpt("format").desc("Output format to use.").hasArg().argName("format").build()); opts.addOption(Option.builder("f").longOpt("fresh").desc("Generate fresh keys (set domain parameters before every generation).").build()); opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); @@ -328,7 +347,9 @@ public class ECTester { } sent.add(export); - systemOutLogger.println(Response.toString(sent)); + for (Response r : sent) { + writer.printResponse(r); + } EC_Params exported = new EC_Params(domain, export.getParams()); @@ -357,7 +378,7 @@ public class ECTester { while (generated < cfg.generateAmount || cfg.generateAmount == 0) { if ((cfg.fresh || generated == 0) && curve != null) { Response fresh = curve.send(); - systemOutLogger.println(fresh.toString()); + logger.println(fresh.toString()); } Command.Generate generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL); @@ -375,7 +396,7 @@ public class ECTester { break; } } - systemOutLogger.println(response.toString()); + logger.println(response.toString()); String pub = Util.bytesToHex(export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_W), false); String priv = Util.bytesToHex(export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S), false); @@ -385,7 +406,7 @@ public class ECTester { generated++; } Response cleanup = new Command.Cleanup(cardManager).send(); - systemOutLogger.println(cleanup.toString()); + logger.println(cleanup.toString()); keysFile.close(); } @@ -401,10 +422,10 @@ public class ECTester { switch (cfg.testSuite) { case "default": - suite = new TestSuite.Default(dataStore, cfg, systemOutLogger); + suite = new TestSuite.Default(dataStore, cfg, writer); break; case "test-vectors": - suite = new TestSuite.TestVectors(dataStore, cfg, systemOutLogger); + suite = new TestSuite.TestVectors(dataStore, cfg, writer); break; default: // These tests are dangerous, prompt before them. @@ -413,8 +434,8 @@ public class ECTester { if (!cfg.yes) { System.out.print("Do you want to proceed? (y/n): "); Scanner in = new Scanner(System.in); - String confirmation = in.nextLine(); - if (!Arrays.asList("yes", "YES", "y", "Y").contains(confirmation)) { + String confirmation = in.nextLine().toLowerCase(); + if (!Arrays.asList("yes","y").contains(confirmation)) { return; } in.close(); @@ -423,13 +444,13 @@ public class ECTester { switch (cfg.testSuite) { case "wrong": - suite = new TestSuite.Wrong(dataStore, cfg, systemOutLogger); + suite = new TestSuite.Wrong(dataStore, cfg, writer); break; case "composite": - suite = new TestSuite.Composite(dataStore, cfg, systemOutLogger); + suite = new TestSuite.Composite(dataStore, cfg, writer); break; case "invalid": - suite = new TestSuite.Invalid(dataStore, cfg, systemOutLogger); + suite = new TestSuite.Invalid(dataStore, cfg, writer); break; default: System.err.println("Unknown test suite."); @@ -455,7 +476,9 @@ public class ECTester { if (curve != null) prepare.add(curve.send()); - systemOutLogger.println(Response.toString(prepare)); + for (Response r : prepare) { + writer.printResponse(r); + } byte pubkey = (cfg.anyPublicKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; byte privkey = (cfg.anyPrivateKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; @@ -479,7 +502,9 @@ public class ECTester { Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send(); ecdh.add(perform); - systemOutLogger.println(Response.toString(ecdh)); + for (Response r : ecdh) { + writer.printResponse(r); + } if (!perform.successful() || !perform.hasSecret()) { if (retry < 10) { @@ -498,7 +523,7 @@ public class ECTester { ++done; } Response cleanup = new Command.Cleanup(cardManager).send(); - systemOutLogger.println(cleanup.toString()); + logger.println(cleanup.toString()); if (out != null) out.close(); @@ -536,7 +561,9 @@ public class ECTester { if (curve != null) prepare.add(curve.send()); - systemOutLogger.println(Response.toString(prepare)); + for (Response r : prepare) { + writer.printResponse(r); + } FileWriter out = null; if (cfg.output != null) { @@ -552,7 +579,9 @@ public class ECTester { Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, data).send(); ecdsa.add(perform); - systemOutLogger.println(Response.toString(ecdsa)); + for (Response r : ecdsa) { + writer.printResponse(r); + } if (!perform.successful() || !perform.hasSignature()) { if (retry < 10) { @@ -571,7 +600,7 @@ public class ECTester { ++done; } Response cleanup = new Command.Cleanup(cardManager).send(); - systemOutLogger.println(cleanup.toString()); + logger.println(cleanup.toString()); if (out != null) out.close(); @@ -617,6 +646,7 @@ public class ECTester { public boolean fresh = false; public boolean simulate = false; public boolean yes = false; + public String format; //Action-related options public String listNamed; @@ -666,6 +696,7 @@ public class ECTester { fresh = cli.hasOption("fresh"); simulate = cli.hasOption("simulate"); yes = cli.hasOption("yes"); + format = cli.getOptionValue("format"); if (cli.hasOption("list-named")) { listNamed = cli.getOptionValue("list-named"); diff --git a/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java new file mode 100644 index 0000000..c20771d --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java @@ -0,0 +1,29 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class HTMLOutputWriter implements OutputWriter { + @Override + public void begin() { + + } + + @Override + public void printResponse(Response r) { + + } + + @Override + public void printTest(Test t) { + + } + + @Override + public void end() { + + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/OutputLogger.java b/src/cz/crcs/ectester/reader/output/OutputLogger.java new file mode 100644 index 0000000..bf47a1f --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/OutputLogger.java @@ -0,0 +1,60 @@ +package cz.crcs.ectester.reader.output; + +import java.io.*; +import java.util.LinkedList; +import java.util.List; + +/** + * @author Petr Svenda petr@svenda.com + * @author Jan Jancar johny@neuromancer.sk + */ +public class OutputLogger { + private OutputStream out; + private PrintStream print; + + public OutputLogger(boolean systemOut, String... filePaths) throws IOException { + List streams = new LinkedList<>(); + for (String filePath : filePaths) { + if (filePath != null) { + streams.add(new FileOutputStream(filePath)); + } + } + if (systemOut) { + streams.add(System.out); + } + this.out = new TeeOutputStream(streams.toArray(new OutputStream[0])); + this.print = new PrintStream(this.out); + } + + public OutputLogger(String filePath) throws IOException { + this(true, filePath); + } + + public OutputStream getOutputStream() { + return this.out; + } + + public PrintStream getPrintStream() { + return this.print; + } + + public void println() { + print.println(); + } + + public void println(String logLine) { + print.println(logLine); + } + + public void print(String logLine) { + print.print(logLine); + } + + public void flush() { + print.flush(); + } + + public void close() { + print.close(); + } +} diff --git a/src/cz/crcs/ectester/reader/output/OutputWriter.java b/src/cz/crcs/ectester/reader/output/OutputWriter.java new file mode 100644 index 0000000..ddcef8c --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/OutputWriter.java @@ -0,0 +1,14 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public interface OutputWriter { + void begin(); + void printResponse(Response r); + void printTest(Test t); + void end(); +} diff --git a/src/cz/crcs/ectester/reader/output/TeeOutputStream.java b/src/cz/crcs/ectester/reader/output/TeeOutputStream.java new file mode 100644 index 0000000..e18d32b --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TeeOutputStream.java @@ -0,0 +1,36 @@ +package cz.crcs.ectester.reader.output; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TeeOutputStream extends OutputStream { + private OutputStream[] outputs; + + public TeeOutputStream(OutputStream... outputs) { + this.outputs = outputs; + } + + @Override + public void write(int b) throws IOException { + for (OutputStream out : outputs) { + out.write(b); + } + } + + @Override + public void flush() throws IOException { + for (OutputStream out :outputs) { + out.flush(); + } + } + + @Override + public void close() throws IOException { + for (OutputStream out :outputs) { + out.close(); + } + } +} diff --git a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java new file mode 100644 index 0000000..7e62e89 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java @@ -0,0 +1,72 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TextOutputWriter implements OutputWriter { + private PrintStream output; + + public TextOutputWriter(PrintStream output) { + this.output = output; + } + + @Override + public void begin() { + } + + private String testPrefix(Test t) { + return (t.ok() ? "OK" : "NOK"); + } + + private String responseSuffix(Response r) { + StringBuilder suffix = new StringBuilder(); + for (int j = 0; j < r.getNumSW(); ++j) { + short sw = r.getSW(j); + if (sw != 0) { + suffix.append(" ").append(Util.getSWString(sw)); + } + } + if (suffix.length() == 0) { + suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]"); + } + return String.format("%4d ms : %s", r.getDuration() / 1000000, suffix); + } + + @Override + public void printResponse(Response r) { + String out = ""; + out += String.format("%-62s:", r.getDescription()) + " : "; + out += responseSuffix(r); + output.println(out); + output.flush(); + } + + @Override + public void printTest(Test t) { + if (!t.hasRun()) + return; + + String out = ""; + if (t instanceof Test.Simple) { + Test.Simple test = (Test.Simple) t; + out += String.format("%-62s:", testPrefix(t) + " " + test.getDescription()) + " : "; + out += responseSuffix(test.getResponse()); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) t; + out += String.format("%-62s:", testPrefix(t) + " " + test.getDescription()); + } + + output.println(out); + output.flush(); + } + + @Override + public void end() { + } +} diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java new file mode 100644 index 0000000..2755501 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java @@ -0,0 +1,29 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class XMLOutputWriter implements OutputWriter { + @Override + public void begin() { + + } + + @Override + public void printResponse(Response r) { + + } + + @Override + public void printTest(Test t) { + + } + + @Override + public void end() { + + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 59b24fc..962261e 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -114,46 +114,7 @@ public abstract class Response { return this.success; } - @Override - public abstract String toString(); - - public String toString(String inner) { - StringBuilder suffix = new StringBuilder(); - for (int j = 0; j < getNumSW(); ++j) { - short sw = getSW(j); - if (sw != 0) { - suffix.append(" ").append(Util.getSWString(sw)); - } - } - if (suffix.length() == 0) { - suffix.append(" [").append(Util.getSW(getNaturalSW())).append("]"); - } - return String.format("%-62s:%4d ms : %s", inner, time / 1000000, suffix); - } - - public static String toString(List responses) { - return toString(responses, null); - } - - public static String toString(List responses, String prefix) { - if (prefix != null) - prefix += " | "; - StringBuilder out = new StringBuilder(); - for (int i = 0; i < responses.size(); ++i) { - Response r = responses.get(i); - - if (prefix != null) - out.append(prefix); - - String message = r.toString(); - out.append(message); - if (i < responses.size() - 1) { - out.append("\n"); - } - } - return out.toString(); - } - + public abstract String getDescription(); /** * @@ -168,8 +129,8 @@ public abstract class Response { } @Override - public String toString() { - return super.toString(String.format("Allocate KeyAgreement(%s) object", Util.getKATypeString(this.kaType))); + public String getDescription() { + return String.format("Allocated KeyAgreement(%s) object", Util.getKATypeString(this.kaType)); } } @@ -193,7 +154,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String field = keyClass == KeyPair.ALG_EC_FP ? "ALG_EC_FP" : "ALG_EC_F2M"; String key; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { @@ -201,7 +162,7 @@ public abstract class Response { } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Allocated %s %db %s", key, keyLength, field)); + return String.format("Allocated %s %db %s", key, keyLength, field); } } @@ -223,14 +184,14 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String key; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { key = "both keypairs"; } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Cleared %s", key)); + return String.format("Cleared %s", key); } } @@ -257,7 +218,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String name; switch (curve) { case EC_Consts.CURVE_default: @@ -287,7 +248,7 @@ public abstract class Response { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Set %s %s parameters on %s", name, what, pair)); + return String.format("Set %s %s parameters on %s", name, what, pair); } } @@ -317,7 +278,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String corrupt = Util.getCorruption(corruption); String pair; @@ -326,7 +287,7 @@ public abstract class Response { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Corrupted params of %s, %s", pair, corrupt)); + return String.format("Corrupted params of %s, %s", pair, corrupt); } } @@ -348,14 +309,14 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String key; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { key = "both keypairs"; } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Generated %s", key)); + return String.format("Generated %s", key); } } @@ -452,7 +413,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String source; if (key == EC_Consts.KEY_BOTH) { source = "both keys"; @@ -465,7 +426,7 @@ public abstract class Response { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return super.toString(String.format("Exported params from %s of %s", source, pair)); + return String.format("Exported params from %s of %s", source, pair); } } @@ -504,7 +465,7 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String algo = Util.getKA(type); String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; @@ -516,7 +477,7 @@ public abstract class Response { } else { validity = Util.getCorruption(corruption); } - return super.toString(String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity)); + return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity); } } @@ -547,10 +508,10 @@ public abstract class Response { } @Override - public String toString() { + public String getDescription() { String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String data = raw == null ? "random" : "provided"; - return super.toString(String.format("ECDSA with %s keypair(%s data)", key, data)); + return String.format("ECDSA with %s keypair(%s data)", key, data); } } @@ -566,8 +527,8 @@ public abstract class Response { } @Override - public String toString() { - return super.toString("Requested JCSystem object deletion"); + public String getDescription() { + return "Requested JCSystem object deletion"; } } @@ -584,8 +545,8 @@ public abstract class Response { } @Override - public String toString() { - return super.toString("Support of ECDH, ECDHC, ECDSA"); + public String getDescription() { + return "Support of ECDH, ECDHC, ECDSA"; } } } diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index cd0cf49..cb885e5 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -31,6 +31,8 @@ public abstract class Test { public abstract void run() throws CardException; + public abstract String getDescription(); + /** * A result of a Test. */ @@ -93,12 +95,8 @@ public abstract class Test { } @Override - public String toString() { - if (hasRun) { - return (ok() ? "OK " : "NOK") + " " + response.toString(); - } else { - return ""; - } + public String getDescription() { + return response.getDescription(); } } @@ -140,6 +138,10 @@ public abstract class Test { }, any); } + public Test[] getTests() { + return tests; + } + @Override public boolean ok() { return result == Result.SUCCESS; @@ -147,10 +149,15 @@ public abstract class Test { @Override public void run() throws CardException { - for (Test test: tests) { + for (Test test : tests) { test.run(); } result = callback.apply(tests); } + + @Override + public String getDescription() { + return ""; + } } } diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 7ce9e0f..33c462f 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -4,11 +4,12 @@ import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; -import cz.crcs.ectester.reader.DirtyLogger; +import cz.crcs.ectester.reader.output.OutputLogger; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.*; +import cz.crcs.ectester.reader.output.OutputWriter; import cz.crcs.ectester.reader.response.Response; import javacard.security.KeyPair; @@ -23,24 +24,26 @@ public abstract class TestSuite { EC_Store dataStore; ECTester.Config cfg; - DirtyLogger systemOut; + OutputWriter writer; String name; List tests = new LinkedList<>(); - TestSuite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut, String name) { + TestSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer, String name) { this.dataStore = dataStore; this.cfg = cfg; - this.systemOut = systemOut; + this.writer = writer; this.name = name; } public List run(CardMngr cardManager) throws CardException, IOException { + writer.begin(); for (Test t : tests) { if (!t.hasRun()) { t.run(); - systemOut.println(t.toString()); + writer.printTest(t); } } + writer.end(); return tests; } @@ -104,8 +107,8 @@ public abstract class TestSuite { public static class Default extends TestSuite { - public Default(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "default"); + public Default(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "default"); } @Override @@ -157,8 +160,8 @@ public abstract class TestSuite { public static class TestVectors extends TestSuite { - public TestVectors(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "test"); + public TestVectors(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "test"); } @Override @@ -213,8 +216,8 @@ public abstract class TestSuite { public static class Composite extends TestSuite { - public Composite(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "composite"); + public Composite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "composite"); } @Override @@ -252,8 +255,8 @@ public abstract class TestSuite { public static class Invalid extends TestSuite { - public Invalid(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "invalid"); + public Invalid(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "invalid"); } @Override @@ -299,8 +302,8 @@ public abstract class TestSuite { public static class Wrong extends TestSuite { - public Wrong(EC_Store dataStore, ECTester.Config cfg, DirtyLogger systemOut) { - super(dataStore, cfg, systemOut, "wrong"); + public Wrong(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "wrong"); } @Override -- cgit v1.2.3-70-g09d2 From dfd0247c88b730300b1e9df64d8331b79524ffc2 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 16 Oct 2017 00:09:49 +0200 Subject: Implement a basic XMLOutputWriter. --- src/cz/crcs/ectester/reader/ECTester.java | 5 +- .../crcs/ectester/reader/output/OutputWriter.java | 4 + .../ectester/reader/output/XMLOutputWriter.java | 93 +++++++++++++++++++++- src/cz/crcs/ectester/reader/test/Test.java | 9 ++- 4 files changed, 104 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index c0c282c..0d558cb 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -35,6 +35,7 @@ import javacard.security.KeyPair; import org.apache.commons.cli.*; import javax.smartcardio.CardException; +import javax.xml.parsers.ParserConfigurationException; import java.io.*; import java.nio.file.Files; import java.util.*; @@ -113,7 +114,7 @@ public class ECTester { writer = new TextOutputWriter(logger.getPrintStream()); break; case "xml": - writer = new XMLOutputWriter(); + writer = new XMLOutputWriter(logger.getOutputStream()); break; case "html": writer = new HTMLOutputWriter(); @@ -177,6 +178,8 @@ public class ECTester { } catch (CardException ex) { if (logger != null) logger.println(ex.getMessage()); + } catch (ParserConfigurationException e) { + e.printStackTrace(); } finally { if (logger != null) logger.flush(); diff --git a/src/cz/crcs/ectester/reader/output/OutputWriter.java b/src/cz/crcs/ectester/reader/output/OutputWriter.java index ddcef8c..761d712 100644 --- a/src/cz/crcs/ectester/reader/output/OutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/OutputWriter.java @@ -3,6 +3,10 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.Test; +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; + /** * @author Jan Jancar johny@neuromancer.sk */ diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java index 2755501..4f72a16 100644 --- a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java @@ -1,29 +1,118 @@ package cz.crcs.ectester.reader.output; +import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.*; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.OutputStream; /** * @author Jan Jancar johny@neuromancer.sk */ public class XMLOutputWriter implements OutputWriter { + private OutputStream output; + private Document doc; + private Node root; + + public XMLOutputWriter(OutputStream output) throws ParserConfigurationException { + this.output = output; + this.doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } + @Override public void begin() { + root = doc.createElement("testRun"); + doc.appendChild(root); + } + + private Element responseElement(Response r) { + Element responseElem = doc.createElement("response"); + responseElem.setAttribute("successful", r.successful() ? "true" : "false"); + + Element apdu = doc.createElement("apdu"); + apdu.setTextContent(Util.bytesToHex(r.getAPDU().getBytes())); + responseElem.appendChild(apdu); + + Element naturalSW = doc.createElement("natural-sw"); + naturalSW.setTextContent(String.valueOf(r.getNaturalSW())); + responseElem.appendChild(naturalSW); + + Element sws = doc.createElement("sws"); + for (int i = 0; i < r.getNumSW(); ++i) { + Element sw = doc.createElement("sw"); + sw.setTextContent(String.valueOf(r.getSW(i))); + sws.appendChild(sw); + } + responseElem.appendChild(sws); + Element duration = doc.createElement("duration"); + duration.setTextContent(String.valueOf(r.getDuration())); + responseElem.appendChild(duration); + + Element description = doc.createElement("desc"); + description.setTextContent(r.getDescription()); + responseElem.appendChild(description); + + return responseElem; } @Override public void printResponse(Response r) { + root.appendChild(responseElement(r)); + } + + private Element testElement(Test t) { + Element testElem = doc.createElement("test"); + + if (t instanceof Test.Simple) { + Test.Simple test = (Test.Simple) t; + testElem.setAttribute("type", "simple"); + testElem.appendChild(responseElement(test.getResponse())); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) t; + testElem.setAttribute("type", "compound"); + for (Test innerTest : test.getTests()) { + testElem.appendChild(testElement(innerTest)); + } + } + Element description = doc.createElement("desc"); + description.setTextContent(t.getDescription()); + testElem.appendChild(description); + + Element result = doc.createElement("result"); + result.setTextContent(t.getResult().toString()); + testElem.appendChild(result); + + return testElem; } @Override public void printTest(Test t) { - + if (!t.hasRun()) + return; + root.appendChild(testElement(t)); } @Override public void end() { - + try { + DOMSource domSource = new DOMSource(doc); + StreamResult result = new StreamResult(output); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.transform(domSource, result); + } catch (TransformerException e) { + e.printStackTrace(); + } } } \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index cb885e5..92c2ebb 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -23,6 +23,8 @@ public abstract class Test { return result; } + public abstract String getDescription(); + public boolean hasRun() { return hasRun; } @@ -31,7 +33,6 @@ public abstract class Test { public abstract void run() throws CardException; - public abstract String getDescription(); /** * A result of a Test. @@ -112,11 +113,11 @@ public abstract class Test { this.tests = tests; } - public Compound function(Function callback, Test... tests) { + public static Compound function(Function callback, Test... tests) { return new Compound(callback, tests); } - public Compound all(Result what, Test... all) { + public static Compound all(Result what, Test... all) { return new Compound((tests) -> { for (Test test : tests) { if (test.getResult() != what) { @@ -127,7 +128,7 @@ public abstract class Test { }, all); } - public Compound any(Result what, Test... any) { + public static Compound any(Result what, Test... any) { return new Compound((tests) -> { for (Test test : tests) { if (test.getResult() == what) { -- cgit v1.2.3-70-g09d2 From 697482644f1d264bff8ffca8a5ac5d71058a4654 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 24 Oct 2017 19:03:06 +0200 Subject: Rename some OutputWriter methods, add YAMLOutputWriter. --- src/cz/crcs/ectester/reader/ECTester.java | 10 ++++---- .../ectester/reader/output/HTMLOutputWriter.java | 29 ---------------------- .../crcs/ectester/reader/output/OutputWriter.java | 4 +-- .../ectester/reader/output/TextOutputWriter.java | 4 +-- .../ectester/reader/output/XMLOutputWriter.java | 4 +-- .../ectester/reader/output/YAMLOutputWriter.java | 29 ++++++++++++++++++++++ src/cz/crcs/ectester/reader/test/TestSuite.java | 19 +++++++------- 7 files changed, 49 insertions(+), 50 deletions(-) delete mode 100644 src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 0d558cb..1b69998 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -351,7 +351,7 @@ public class ECTester { sent.add(export); for (Response r : sent) { - writer.printResponse(r); + writer.outputResponse(r); } EC_Params exported = new EC_Params(domain, export.getParams()); @@ -480,7 +480,7 @@ public class ECTester { prepare.add(curve.send()); for (Response r : prepare) { - writer.printResponse(r); + writer.outputResponse(r); } byte pubkey = (cfg.anyPublicKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; @@ -506,7 +506,7 @@ public class ECTester { Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send(); ecdh.add(perform); for (Response r : ecdh) { - writer.printResponse(r); + writer.outputResponse(r); } if (!perform.successful() || !perform.hasSecret()) { @@ -565,7 +565,7 @@ public class ECTester { prepare.add(curve.send()); for (Response r : prepare) { - writer.printResponse(r); + writer.outputResponse(r); } FileWriter out = null; @@ -583,7 +583,7 @@ public class ECTester { Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, data).send(); ecdsa.add(perform); for (Response r : ecdsa) { - writer.printResponse(r); + writer.outputResponse(r); } if (!perform.successful() || !perform.hasSignature()) { diff --git a/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java deleted file mode 100644 index c20771d..0000000 --- a/src/cz/crcs/ectester/reader/output/HTMLOutputWriter.java +++ /dev/null @@ -1,29 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class HTMLOutputWriter implements OutputWriter { - @Override - public void begin() { - - } - - @Override - public void printResponse(Response r) { - - } - - @Override - public void printTest(Test t) { - - } - - @Override - public void end() { - - } -} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/OutputWriter.java b/src/cz/crcs/ectester/reader/output/OutputWriter.java index 761d712..09185b1 100644 --- a/src/cz/crcs/ectester/reader/output/OutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/OutputWriter.java @@ -12,7 +12,7 @@ import javax.xml.transform.TransformerException; */ public interface OutputWriter { void begin(); - void printResponse(Response r); - void printTest(Test t); + void outputResponse(Response r); + void outputTest(Test t); void end(); } diff --git a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java index 7e62e89..6887f61 100644 --- a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java @@ -39,7 +39,7 @@ public class TextOutputWriter implements OutputWriter { } @Override - public void printResponse(Response r) { + public void outputResponse(Response r) { String out = ""; out += String.format("%-62s:", r.getDescription()) + " : "; out += responseSuffix(r); @@ -48,7 +48,7 @@ public class TextOutputWriter implements OutputWriter { } @Override - public void printTest(Test t) { + public void outputTest(Test t) { if (!t.hasRun()) return; diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java index 4f72a16..b9f8c8f 100644 --- a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java @@ -65,7 +65,7 @@ public class XMLOutputWriter implements OutputWriter { } @Override - public void printResponse(Response r) { + public void outputResponse(Response r) { root.appendChild(responseElement(r)); } @@ -96,7 +96,7 @@ public class XMLOutputWriter implements OutputWriter { } @Override - public void printTest(Test t) { + public void outputTest(Test t) { if (!t.hasRun()) return; root.appendChild(testElement(t)); diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java new file mode 100644 index 0000000..34ff29a --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java @@ -0,0 +1,29 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class YAMLOutputWriter implements OutputWriter { + @Override + public void begin() { + + } + + @Override + public void outputResponse(Response r) { + + } + + @Override + public void outputTest(Test t) { + + } + + @Override + public void end() { + + } +} diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 33c462f..8369439 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -4,7 +4,6 @@ import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; -import cz.crcs.ectester.reader.output.OutputLogger; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.command.Command; @@ -40,7 +39,7 @@ public abstract class TestSuite { for (Test t : tests) { if (!t.hasRun()) { t.run(); - writer.printTest(t); + writer.outputTest(t); } } writer.end(); @@ -62,7 +61,7 @@ public abstract class TestSuite { * @param ecdsaExpected expected result of the ordinary ECDSA command * @return tests to run */ - List testCurve(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List defaultCurveTests(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { List tests = new LinkedList<>(); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); @@ -87,7 +86,7 @@ public abstract class TestSuite { * @param ecdsaExpected expected result of the ordinary ECDSA command * @return tests to run */ - List testCategory(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List defaultCategoryTests(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { List tests = new LinkedList<>(); Map curves = dataStore.getObjects(EC_Curve.class, category); if (curves == null) @@ -97,7 +96,7 @@ public abstract class TestSuite { if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); - tests.addAll(testCurve(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); + tests.addAll(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } @@ -116,10 +115,10 @@ public abstract class TestSuite { tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); if (cfg.namedCurve != null) { if (cfg.primeField) { - tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); } if (cfg.binaryField) { - tests.addAll(testCategory(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); } } else { if (cfg.all) { @@ -153,7 +152,7 @@ public abstract class TestSuite { Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); - tests.addAll(testCurve(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCurveTests(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } @@ -312,10 +311,10 @@ public abstract class TestSuite { * These should generally fail, the curves aren't curves. */ if (cfg.primeField) { - tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); } if (cfg.binaryField) { - tests.addAll(testCategory(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); } return super.run(cardManager); } -- cgit v1.2.3-70-g09d2 From e92f0b326d51d89d66a34953af9b568a820e6205 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 24 Oct 2017 19:15:24 +0200 Subject: Add SnakeYAML library to output YAML. --- dist/lib/snakeyaml-1.19.jar | Bin 0 -> 297518 bytes lib/snakeyaml-1.19.jar | Bin 0 -> 297518 bytes manifest.mf | 3 +-- nbproject/project.properties | 3 ++- src/cz/crcs/ectester/reader/ECTester.java | 11 ++++++++--- 5 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 dist/lib/snakeyaml-1.19.jar create mode 100644 lib/snakeyaml-1.19.jar (limited to 'src') diff --git a/dist/lib/snakeyaml-1.19.jar b/dist/lib/snakeyaml-1.19.jar new file mode 100644 index 0000000..7c73a76 Binary files /dev/null and b/dist/lib/snakeyaml-1.19.jar differ diff --git a/lib/snakeyaml-1.19.jar b/lib/snakeyaml-1.19.jar new file mode 100644 index 0000000..7c73a76 Binary files /dev/null and b/lib/snakeyaml-1.19.jar differ diff --git a/manifest.mf b/manifest.mf index fdec036..2cb1a50 100644 --- a/manifest.mf +++ b/manifest.mf @@ -1,5 +1,4 @@ Manifest-Version: 1.0 -X-COMMENT: Main-Class will be added automatically by build -Class-Path: lib/jcardsim-3.0.4-SNAPSHOT.jar lib/commons-cli-1.3.1.jar +Class-Path: lib/jcardsim-3.0.4-SNAPSHOT.jar lib/commons-cli-1.3.1.jar lib/snakeyaml-1.19.jar Main-Class: cz.crcs.ectester.reader.ECTester diff --git a/nbproject/project.properties b/nbproject/project.properties index ad90c49..16be542 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -33,7 +33,8 @@ includes=** jar.compress=false javac.classpath=\ lib/jcardsim-3.0.4-SNAPSHOT.jar:\ - lib/commons-cli-1.3.1.jar + lib/commons-cli-1.3.1.jar:\ + lib/snakeyaml-1.19.jar # Space-separated list of extra javac options javac.compilerargs= javac.deprecation=false diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 1b69998..016e095 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -116,8 +116,8 @@ public class ECTester { case "xml": writer = new XMLOutputWriter(logger.getOutputStream()); break; - case "html": - writer = new HTMLOutputWriter(); + case "yaml": + writer = new YAMLOutputWriter(); break; } } @@ -699,13 +699,18 @@ public class ECTester { fresh = cli.hasOption("fresh"); simulate = cli.hasOption("simulate"); yes = cli.hasOption("yes"); - format = cli.getOptionValue("format"); if (cli.hasOption("list-named")) { listNamed = cli.getOptionValue("list-named"); return true; } + format = cli.getOptionValue("format"); + if (!Arrays.asList("text", "xml", "yaml").contains(format)) { + System.err.println("Wrong output format " + format + "."); + return false; + } + if ((key != null || namedKey != null) && (anyPublicKey || anyPrivateKey)) { System.err.print("Can only specify the whole key with --key/--named-key or pubkey and privkey with --public/--named-public and --private/--named-private."); return false; -- cgit v1.2.3-70-g09d2 From 2cca70889abe82d76de239007e93ed3b85f74191 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 24 Oct 2017 22:49:02 +0200 Subject: Implement YAMLOutputWriter. --- src/cz/crcs/ectester/reader/ECTester.java | 2 +- .../ectester/reader/output/YAMLOutputWriter.java | 64 +++++++++++++++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 016e095..be09986 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -117,7 +117,7 @@ public class ECTester { writer = new XMLOutputWriter(logger.getOutputStream()); break; case "yaml": - writer = new YAMLOutputWriter(); + writer = new YAMLOutputWriter(logger.getPrintStream()); break; } } diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java index 34ff29a..e81cbad 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java @@ -1,29 +1,89 @@ package cz.crcs.ectester.reader.output; +import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.Test; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import java.io.PrintStream; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; /** * @author Jan Jancar johny@neuromancer.sk */ public class YAMLOutputWriter implements OutputWriter { + private PrintStream output; + private List testRun; + + public YAMLOutputWriter(PrintStream output) { + this.output = output; + } + @Override public void begin() { + output.println("---"); + testRun = new LinkedList<>(); + } + private Map responseObject(Response r) { + Map responseObj = new HashMap<>(); + responseObj.put("successful", r.successful()); + responseObj.put("apdu", Util.bytesToHex(r.getAPDU().getBytes())); + responseObj.put("natural_sw", r.getNaturalSW()); + List sws = new LinkedList<>(); + for (int i = 0; i < r.getNumSW(); ++i) { + sws.add(r.getSW(i)); + } + responseObj.put("sws", sws); + responseObj.put("duration", r.getDuration()); + responseObj.put("desc", r.getDescription()); + return responseObj; } @Override public void outputResponse(Response r) { + testRun.add(responseObject(r)); + } + private Map testObject(Test t) { + Map testObj = new HashMap<>(); + + if (t instanceof Test.Simple) { + Test.Simple test = (Test.Simple) t; + testObj.put("type", "simple"); + testObj.put("response", responseObject(test.getResponse())); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) t; + testObj.put("type", "compound"); + List> tests = new LinkedList<>(); + for (Test innerTest : test.getTests()) { + tests.add(testObject(innerTest)); + } + testObj.put("tests", tests); + } + + testObj.put("desc", t.getDescription()); + testObj.put("result", t.getResult().name()); + + return testObj; } @Override public void outputTest(Test t) { - + testRun.add(testObject(t)); } @Override public void end() { - + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + Yaml yaml = new Yaml(options); + String out = yaml.dump(testRun); + output.println(out); + output.println("---"); } } -- cgit v1.2.3-70-g09d2 From 76d5e632d26515a6490009d0781604f3a1f2621f Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 24 Oct 2017 23:07:34 +0200 Subject: Fix output when missing output format option. --- src/cz/crcs/ectester/reader/ECTester.java | 2 +- src/cz/crcs/ectester/reader/test/Test.java | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index be09986..1d12d00 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -705,7 +705,7 @@ public class ECTester { return true; } - format = cli.getOptionValue("format"); + format = cli.getOptionValue("format", "text"); if (!Arrays.asList("text", "xml", "yaml").contains(format)) { System.err.println("Wrong output format " + format + "."); return false; diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 92c2ebb..14cf554 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -107,6 +107,7 @@ public abstract class Test { public static class Compound extends Test { private Function callback; private Test[] tests; + private String description; private Compound(Function callback, Test... tests) { this.callback = callback; @@ -156,9 +157,13 @@ public abstract class Test { result = callback.apply(tests); } + public void setDescription(String description) { + this.description = description; + } + @Override public String getDescription() { - return ""; + return description; } } } -- cgit v1.2.3-70-g09d2 From ffbbf6e6482d48f4d49dd2ba1a63f687978415f8 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 00:10:56 +0200 Subject: Add Compund test to test-vectors suite. --- .../ectester/reader/output/TextOutputWriter.java | 24 ++++++++----- .../ectester/reader/output/YAMLOutputWriter.java | 6 +++- src/cz/crcs/ectester/reader/test/Test.java | 39 ++++++++++++++++++++++ src/cz/crcs/ectester/reader/test/TestSuite.java | 29 +++++++++++++--- 4 files changed, 83 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java index 6887f61..d9669be 100644 --- a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java @@ -47,22 +47,28 @@ public class TextOutputWriter implements OutputWriter { output.flush(); } - @Override - public void outputTest(Test t) { + private String testString(Test t) { if (!t.hasRun()) - return; + return null; - String out = ""; + StringBuilder out = new StringBuilder(); if (t instanceof Test.Simple) { Test.Simple test = (Test.Simple) t; - out += String.format("%-62s:", testPrefix(t) + " " + test.getDescription()) + " : "; - out += responseSuffix(test.getResponse()); - } else if (t instanceof Test.Compound) { + out.append(String.format("%-62s:", testPrefix(t) + " " + test.getDescription())).append(" : "); + out.append(responseSuffix(test.getResponse())); + } else if (t instanceof Test.Compound) { Test.Compound test = (Test.Compound) t; - out += String.format("%-62s:", testPrefix(t) + " " + test.getDescription()); + for (Test innerTest : test.getTests()) { + out.append(" ").append(testString(innerTest)).append(System.lineSeparator()); + } + out.append(String.format("%-62s:", testPrefix(t) + " " + test.getDescription())); } + return out.toString(); + } - output.println(out); + @Override + public void outputTest(Test t) { + output.println(testString(t)); output.flush(); } diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java index e81cbad..211bd47 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java @@ -82,7 +82,11 @@ public class YAMLOutputWriter implements OutputWriter { DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); Yaml yaml = new Yaml(options); - String out = yaml.dump(testRun); + + Map> result = new HashMap<>(); + result.put("testRun", testRun); + String out = yaml.dump(result); + output.println(out); output.println("---"); } diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 14cf554..f873c19 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -114,10 +114,19 @@ public abstract class Test { this.tests = tests; } + private Compound(Function callback, String descripiton, Test... tests) { + this(callback, tests); + this.description = descripiton; + } + public static Compound function(Function callback, Test... tests) { return new Compound(callback, tests); } + public static Compound function(Function callback, String description, Test... tests) { + return new Compound(callback, description, tests); + } + public static Compound all(Result what, Test... all) { return new Compound((tests) -> { for (Test test : tests) { @@ -129,6 +138,12 @@ public abstract class Test { }, all); } + public static Compound all(Result what, String description, Test... all) { + Compound result = Compound.all(what, all); + result.setDescription(description); + return result; + } + public static Compound any(Result what, Test... any) { return new Compound((tests) -> { for (Test test : tests) { @@ -140,6 +155,29 @@ public abstract class Test { }, any); } + public static Compound any(Result what, String description, Test... any) { + Compound result = Compound.any(what, any); + result.setDescription(description); + return result; + } + + public static Compound mask(Result[] results, Test... masked) { + return new Compound((tests) -> { + for (int i = 0; i < results.length; ++i) { + if (results[i] != Result.ANY && results[i] != tests[i].getResult()) { + return Result.FAILURE; + } + } + return Result.SUCCESS; + }, masked); + } + + public static Compound mask(Result[] results, String description, Test... masked) { + Compound result = Compound.mask(results, masked); + result.setDescription(description); + return result; + } + public Test[] getTests() { return tests; } @@ -155,6 +193,7 @@ public abstract class Test { test.run(); } result = callback.apply(tests); + this.hasRun = true; } public void setDescription(String description) { diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 8369439..4bca641 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.reader.test; +import static cz.crcs.ectester.reader.test.Test.Result; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; @@ -104,6 +105,9 @@ public abstract class TestSuite { return tests; } + /** + * + */ public static class Default extends TestSuite { public Default(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { @@ -157,6 +161,9 @@ public abstract class TestSuite { } } + /** + * + */ public static class TestVectors extends TestSuite { public TestVectors(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { @@ -191,13 +198,14 @@ public abstract class TestSuite { if (onekey == null || otherkey == null) { throw new IOException("Test vector keys couldn't be located."); } + List testVector = new LinkedList<>(); - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { Response.ECDH dh = (Response.ECDH) response; if (!dh.successful() || !dh.hasSecret()) return Test.Result.FAILURE; @@ -206,6 +214,8 @@ public abstract class TestSuite { } return Test.Result.SUCCESS; })); + //tests.addAll(testVector); + tests.add(Test.Compound.all(Result.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } @@ -213,6 +223,9 @@ public abstract class TestSuite { } } + /** + * + */ public static class Composite extends TestSuite { public Composite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { @@ -252,6 +265,9 @@ public abstract class TestSuite { } } + /** + * + */ public static class Invalid extends TestSuite { public Invalid(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { @@ -299,6 +315,9 @@ public abstract class TestSuite { } } + /** + * + */ public static class Wrong extends TestSuite { public Wrong(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { -- cgit v1.2.3-70-g09d2 From f70810a70704904850748ba6bf250b415d815462 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 00:27:07 +0200 Subject: Add test.ok() information to XML and YAML outputs. --- src/cz/crcs/ectester/reader/output/XMLOutputWriter.java | 4 ++++ src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java | 1 + 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java index b9f8c8f..7d14cd4 100644 --- a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java @@ -92,6 +92,10 @@ public class XMLOutputWriter implements OutputWriter { result.setTextContent(t.getResult().toString()); testElem.appendChild(result); + Element ok = doc.createElement("ok"); + ok.setTextContent(t.ok() ? "true" : "false"); + testElem.appendChild(ok); + return testElem; } diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java index 211bd47..b42c095 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java @@ -68,6 +68,7 @@ public class YAMLOutputWriter implements OutputWriter { testObj.put("desc", t.getDescription()); testObj.put("result", t.getResult().name()); + testObj.put("ok", t.ok()); return testObj; } -- cgit v1.2.3-70-g09d2 From 3f37a993d1e2d9a2f547d34774ddca2a55804223 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 00:42:57 +0200 Subject: Split TestSuite classes into separate files. --- src/cz/crcs/ectester/reader/ECTester.java | 12 +- .../ectester/reader/test/CompositeCurvesSuite.java | 60 ++++++ src/cz/crcs/ectester/reader/test/DefaultSuite.java | 71 +++++++ .../ectester/reader/test/InvalidCurvesSuite.java | 70 ++++++ src/cz/crcs/ectester/reader/test/TestSuite.java | 234 --------------------- .../crcs/ectester/reader/test/TestVectorSuite.java | 81 +++++++ .../ectester/reader/test/WrongCurvesSuite.java | 36 ++++ 7 files changed, 324 insertions(+), 240 deletions(-) create mode 100644 src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/DefaultSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/TestVectorSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 1d12d00..5a2274d 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -30,7 +30,7 @@ import cz.crcs.ectester.reader.ec.EC_Data; import cz.crcs.ectester.reader.ec.EC_Params; import cz.crcs.ectester.reader.output.*; import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.TestSuite; +import cz.crcs.ectester.reader.test.*; import javacard.security.KeyPair; import org.apache.commons.cli.*; @@ -425,10 +425,10 @@ public class ECTester { switch (cfg.testSuite) { case "default": - suite = new TestSuite.Default(dataStore, cfg, writer); + suite = new DefaultSuite(dataStore, cfg, writer); break; case "test-vectors": - suite = new TestSuite.TestVectors(dataStore, cfg, writer); + suite = new TestVectorSuite(dataStore, cfg, writer); break; default: // These tests are dangerous, prompt before them. @@ -447,13 +447,13 @@ public class ECTester { switch (cfg.testSuite) { case "wrong": - suite = new TestSuite.Wrong(dataStore, cfg, writer); + suite = new WrongCurvesSuite(dataStore, cfg, writer); break; case "composite": - suite = new TestSuite.Composite(dataStore, cfg, writer); + suite = new CompositeCurvesSuite(dataStore, cfg, writer); break; case "invalid": - suite = new TestSuite.Invalid(dataStore, cfg, writer); + suite = new InvalidCurvesSuite(dataStore, cfg, writer); break; default: System.err.println("Unknown test suite."); diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java new file mode 100644 index 0000000..75c6371 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -0,0 +1,60 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.ec.EC_Curve; +import cz.crcs.ectester.reader.ec.EC_Key; +import cz.crcs.ectester.reader.output.OutputWriter; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class CompositeCurvesSuite extends TestSuite { + + public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "composite"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + /* Do the default tests with the public keys set to provided smallorder keys + * over composite order curves. Essentially small subgroup attacks. + * These should fail, the curves aren't safe so that if the computation with + * a small order public key succeeds the private key modulo the public key order + * is revealed. + */ + Map keys = dataStore.getObjects(EC_Key.class, "composite"); + for (EC_Key key : keys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + if ((curve.getBits() == cfg.bits || cfg.all)) { + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + + //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); + //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); + + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + return super.run(cardManager); + } +} diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java new file mode 100644 index 0000000..2024578 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -0,0 +1,71 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.output.OutputWriter; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.List; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class DefaultSuite extends TestSuite { + + public DefaultSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "default"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); + if (cfg.namedCurve != null) { + if (cfg.primeField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + } + if (cfg.binaryField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + } + } else { + if (cfg.all) { + if (cfg.primeField) { + //iterate over prime curve sizes used: EC_Consts.FP_SIZES + for (short keyLength : EC_Consts.FP_SIZES) { + defaultTests(cardManager, keyLength, KeyPair.ALG_EC_FP); + } + } + if (cfg.binaryField) { + //iterate over binary curve sizes used: EC_Consts.F2M_SIZES + for (short keyLength : EC_Consts.F2M_SIZES) { + defaultTests(cardManager, keyLength, KeyPair.ALG_EC_F2M); + } + } + } else { + if (cfg.primeField) { + defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_FP); + } + + if (cfg.binaryField) { + defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_F2M); + } + } + } + return super.run(cardManager); + } + + private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); + Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); + if (curve != null) + tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); + tests.addAll(defaultCurveTests(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + } +} diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java new file mode 100644 index 0000000..20882b6 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -0,0 +1,70 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.ec.EC_Curve; +import cz.crcs.ectester.reader.ec.EC_Key; +import cz.crcs.ectester.reader.output.OutputWriter; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class InvalidCurvesSuite extends TestSuite { + + public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "invalid"); + } + + @Override + public List run(CardMngr cardManager) throws CardException, IOException { + /* Set original curves (secg/nist/brainpool). Generate local. + * Try ECDH with invalid public keys of increasing (or decreasing) order. + */ + Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + Map> curves = new HashMap<>(); + for (EC_Key.Public key : pubkeys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + List keys = curves.getOrDefault(curve, new LinkedList<>()); + keys.add(key); + curves.putIfAbsent(curve, keys); + } + for (Map.Entry> e : curves.entrySet()) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + for (EC_Key.Public pub : keys) { + // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); + // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); + } + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + + return super.run(cardManager); + } +} diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 4bca641..fde2266 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -104,238 +104,4 @@ public abstract class TestSuite { return tests; } - - /** - * - */ - public static class Default extends TestSuite { - - public Default(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "default"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); - if (cfg.namedCurve != null) { - if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - } - if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - } - } else { - if (cfg.all) { - if (cfg.primeField) { - //iterate over prime curve sizes used: EC_Consts.FP_SIZES - for (short keyLength : EC_Consts.FP_SIZES) { - defaultTests(cardManager, keyLength, KeyPair.ALG_EC_FP); - } - } - if (cfg.binaryField) { - //iterate over binary curve sizes used: EC_Consts.F2M_SIZES - for (short keyLength : EC_Consts.F2M_SIZES) { - defaultTests(cardManager, keyLength, KeyPair.ALG_EC_F2M); - } - } - } else { - if (cfg.primeField) { - defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_FP); - } - - if (cfg.binaryField) { - defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_F2M); - } - } - } - return super.run(cardManager); - } - - private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); - Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); - if (curve != null) - tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); - tests.addAll(defaultCurveTests(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - } - - /** - * - */ - public static class TestVectors extends TestSuite { - - public TestVectors(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "test"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. - * Do ECDH both ways, export and verify that the result is correct. - */ - Map results = dataStore.getObjects(EC_KAResult.class, "test"); - for (EC_KAResult result : results.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); - if (cfg.namedCurve != null && !(result.getCurve().startsWith(cfg.namedCurve) || result.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getBits() != cfg.bits && !cfg.all) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); - if (onekey == null) { - onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); - } - EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); - if (otherkey == null) { - otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); - } - if (onekey == null || otherkey == null) { - throw new IOException("Test vector keys couldn't be located."); - } - List testVector = new LinkedList<>(); - - testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { - Response.ECDH dh = (Response.ECDH) response; - if (!dh.successful() || !dh.hasSecret()) - return Test.Result.FAILURE; - if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { - return Test.Result.FAILURE; - } - return Test.Result.SUCCESS; - })); - //tests.addAll(testVector); - tests.add(Test.Compound.all(Result.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); - - } - return super.run(cardManager); - } - } - - /** - * - */ - public static class Composite extends TestSuite { - - public Composite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "composite"); - } - - @Override - public List run(CardMngr cardManager) throws IOException, CardException { - /* Do the default tests with the public keys set to provided smallorder keys - * over composite order curves. Essentially small subgroup attacks. - * These should fail, the curves aren't safe so that if the computation with - * a small order public key succeeds the private key modulo the public key order - * is revealed. - */ - Map keys = dataStore.getObjects(EC_Key.class, "composite"); - for (EC_Key key : keys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); - - //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); - //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); - - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - } - return super.run(cardManager); - } - } - - /** - * - */ - public static class Invalid extends TestSuite { - - public Invalid(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "invalid"); - } - - @Override - public List run(CardMngr cardManager) throws CardException, IOException { - /* Set original curves (secg/nist/brainpool). Generate local. - * Try ECDH with invalid public keys of increasing (or decreasing) order. - */ - Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); - Map> curves = new HashMap<>(); - for (EC_Key.Public key : pubkeys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getBits() != cfg.bits && !cfg.all) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - List keys = curves.getOrDefault(curve, new LinkedList<>()); - keys.add(key); - curves.putIfAbsent(curve, keys); - } - for (Map.Entry> e : curves.entrySet()) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); - for (EC_Key.Public pub : keys) { - // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); - // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); - } - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); - } - - return super.run(cardManager); - } - } - - /** - * - */ - public static class Wrong extends TestSuite { - - public Wrong(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "wrong"); - } - - @Override - public List run(CardMngr cardManager) throws CardException, IOException { - /* Just do the default tests on the wrong curves. - * These should generally fail, the curves aren't curves. - */ - if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); - } - if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); - } - return super.run(cardManager); - } - } } diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java new file mode 100644 index 0000000..69f4ca3 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -0,0 +1,81 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.ec.*; +import cz.crcs.ectester.reader.output.OutputWriter; +import cz.crcs.ectester.reader.response.Response; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class TestVectorSuite extends TestSuite { + + public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "test"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. + * Do ECDH both ways, export and verify that the result is correct. + */ + Map results = dataStore.getObjects(EC_KAResult.class, "test"); + for (EC_KAResult result : results.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); + if (cfg.namedCurve != null && !(result.getCurve().startsWith(cfg.namedCurve) || result.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); + if (onekey == null) { + onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); + } + EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); + if (otherkey == null) { + otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); + } + if (onekey == null || otherkey == null) { + throw new IOException("Test vector keys couldn't be located."); + } + List testVector = new LinkedList<>(); + + testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + Response.ECDH dh = (Response.ECDH) response; + if (!dh.successful() || !dh.hasSecret()) + return Test.Result.FAILURE; + if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { + return Test.Result.FAILURE; + } + return Test.Result.SUCCESS; + })); + tests.add(Test.Compound.all(Test.Result.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + + } + return super.run(cardManager); + } +} diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java new file mode 100644 index 0000000..3346b9f --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -0,0 +1,36 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTester; +import cz.crcs.ectester.reader.output.OutputWriter; +import javacard.security.KeyPair; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.List; + +/** + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class WrongCurvesSuite extends TestSuite { + + public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { + super(dataStore, cfg, writer, "wrong"); + } + + @Override + public List run(CardMngr cardManager) throws CardException, IOException { + /* Just do the default tests on the wrong curves. + * These should generally fail, the curves aren't curves. + */ + if (cfg.primeField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + } + if (cfg.binaryField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + } + return super.run(cardManager); + } +} -- cgit v1.2.3-70-g09d2 From cd2a972ee05c88c2a83e7788839bbd657c2cf1c4 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 18:45:19 +0200 Subject: Fix Command.prepareKey for private key. --- src/cz/crcs/ectester/reader/command/Command.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index bab78c9..3c11456 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -164,7 +164,7 @@ public abstract class Command { priv.readCSV(in); in.close(); } else { - priv = dataStore.getObject(EC_Key.Public.class, cfg.namedPrivateKey); + priv = dataStore.getObject(EC_Key.Private.class, cfg.namedPrivateKey); if (priv == null) { priv = dataStore.getObject(EC_Keypair.class, cfg.namedPrivateKey); } -- cgit v1.2.3-70-g09d2 From 69a4116df7b54ddfdaba2f8aa80ecb9e9a2ed9a7 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 18:58:52 +0200 Subject: Simplify test contract. --- .../ectester/reader/output/TextOutputWriter.java | 20 +++++++++---- .../ectester/reader/output/XMLOutputWriter.java | 4 --- .../ectester/reader/output/YAMLOutputWriter.java | 1 - src/cz/crcs/ectester/reader/test/Test.java | 35 +++++++++------------- .../crcs/ectester/reader/test/TestVectorSuite.java | 2 +- 5 files changed, 29 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java index d9669be..7f9cdae 100644 --- a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java @@ -21,7 +21,7 @@ public class TextOutputWriter implements OutputWriter { } private String testPrefix(Test t) { - return (t.ok() ? "OK" : "NOK"); + return String.format("%-4s", t.getResult() == Test.Result.SUCCESS ? "OK" : "NOK"); } private String responseSuffix(Response r) { @@ -41,7 +41,7 @@ public class TextOutputWriter implements OutputWriter { @Override public void outputResponse(Response r) { String out = ""; - out += String.format("%-62s:", r.getDescription()) + " : "; + out += String.format("%-70s:", r.getDescription()) + " : "; out += responseSuffix(r); output.println(out); output.flush(); @@ -54,14 +54,22 @@ public class TextOutputWriter implements OutputWriter { StringBuilder out = new StringBuilder(); if (t instanceof Test.Simple) { Test.Simple test = (Test.Simple) t; - out.append(String.format("%-62s:", testPrefix(t) + " " + test.getDescription())).append(" : "); + out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())).append(" : "); out.append(responseSuffix(test.getResponse())); } else if (t instanceof Test.Compound) { Test.Compound test = (Test.Compound) t; - for (Test innerTest : test.getTests()) { - out.append(" ").append(testString(innerTest)).append(System.lineSeparator()); + Test[] tests = test.getTests(); + for (int i = 0; i < tests.length; ++i) { + if (i == 0) { + out.append(" /- "); + } else if (i == tests.length - 1) { + out.append(" \\- "); + } else { + out.append(" | "); + } + out.append(testString(tests[i])).append(System.lineSeparator()); } - out.append(String.format("%-62s:", testPrefix(t) + " " + test.getDescription())); + out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())); } return out.toString(); } diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java index 7d14cd4..b9f8c8f 100644 --- a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java @@ -92,10 +92,6 @@ public class XMLOutputWriter implements OutputWriter { result.setTextContent(t.getResult().toString()); testElem.appendChild(result); - Element ok = doc.createElement("ok"); - ok.setTextContent(t.ok() ? "true" : "false"); - testElem.appendChild(ok); - return testElem; } diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java index b42c095..211bd47 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java @@ -68,7 +68,6 @@ public class YAMLOutputWriter implements OutputWriter { testObj.put("desc", t.getDescription()); testObj.put("result", t.getResult().name()); - testObj.put("ok", t.ok()); return testObj; } diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index f873c19..1890e94 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -29,8 +29,6 @@ public abstract class Test { return hasRun; } - public abstract boolean ok(); - public abstract void run() throws CardException; @@ -49,17 +47,20 @@ public abstract class Test { */ public static class Simple extends Test { private BiFunction callback; - private Result expected; private Command command; private Response response; public Simple(Command command, Result expected) { - this.command = command; - this.expected = expected; + this(command, (cmd, resp) -> { + if (expected == Result.ANY) + return Result.SUCCESS; + Result respResult = resp.successful() ? Result.SUCCESS : Result.FAILURE; + return respResult == expected ? Result.SUCCESS : Result.FAILURE; + }); } - public Simple(Command command, Result expected, BiFunction callback) { - this(command, expected); + public Simple(Command command, BiFunction callback) { + this.command = command; this.callback = callback; } @@ -71,17 +72,11 @@ public abstract class Test { return response; } - public Result getExpected() { - return expected; - } - - @Override - public boolean ok() { - return result == expected || expected == Result.ANY; - } - @Override public void run() throws CardException { + if (hasRun) + return; + response = command.send(); if (callback != null) { result = callback.apply(command, response); @@ -182,13 +177,11 @@ public abstract class Test { return tests; } - @Override - public boolean ok() { - return result == Result.SUCCESS; - } - @Override public void run() throws CardException { + if (hasRun) + return; + for (Test test : tests) { test.run(); } diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 69f4ca3..2098ae3 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -63,7 +63,7 @@ public class TestVectorSuite extends TestSuite { //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> { Response.ECDH dh = (Response.ECDH) response; if (!dh.successful() || !dh.hasSecret()) return Test.Result.FAILURE; -- cgit v1.2.3-70-g09d2 From 2c6c2a2d35292368b7263fedb6db508da7ded4c4 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 20:17:07 +0200 Subject: Split ResponseWriter into separate class, introduce TestRunner. --- src/cz/crcs/ectester/reader/ECTester.java | 43 ++++---- .../crcs/ectester/reader/output/OutputWriter.java | 18 ---- .../ectester/reader/output/ResponseWriter.java | 39 +++++++ .../ectester/reader/output/TeeOutputStream.java | 4 +- src/cz/crcs/ectester/reader/output/TestWriter.java | 15 +++ .../ectester/reader/output/TextOutputWriter.java | 86 --------------- .../ectester/reader/output/TextTestWriter.java | 66 ++++++++++++ .../ectester/reader/output/XMLOutputWriter.java | 118 --------------------- .../crcs/ectester/reader/output/XMLTestWriter.java | 117 ++++++++++++++++++++ .../ectester/reader/output/YAMLOutputWriter.java | 93 ---------------- .../ectester/reader/output/YAMLTestWriter.java | 92 ++++++++++++++++ .../ectester/reader/test/CompositeCurvesSuite.java | 9 +- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 11 +- .../ectester/reader/test/InvalidCurvesSuite.java | 11 +- src/cz/crcs/ectester/reader/test/TestRunner.java | 29 +++++ src/cz/crcs/ectester/reader/test/TestSuite.java | 22 +--- .../crcs/ectester/reader/test/TestVectorSuite.java | 10 +- .../ectester/reader/test/WrongCurvesSuite.java | 9 +- 18 files changed, 405 insertions(+), 387 deletions(-) delete mode 100644 src/cz/crcs/ectester/reader/output/OutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/ResponseWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/TestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/TextOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/TextTestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/XMLOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/XMLTestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/YAMLTestWriter.java create mode 100644 src/cz/crcs/ectester/reader/test/TestRunner.java (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 5a2274d..271a8e4 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -52,7 +52,8 @@ public class ECTester { private CardMngr cardManager; private OutputLogger logger; - private OutputWriter writer; + private TestWriter testWriter; + private ResponseWriter respWriter; private EC_Store dataStore; private Config cfg; @@ -105,22 +106,25 @@ public class ECTester { cardManager.send(SELECT_ECTESTERAPPLET); } + // Setup logger, testWriter and respWriter logger = new OutputLogger(true, cfg.log); if (cfg.format == null) { - writer = new TextOutputWriter(logger.getPrintStream()); + testWriter = new TextTestWriter(logger.getPrintStream()); } else { switch (cfg.format) { case "text": - writer = new TextOutputWriter(logger.getPrintStream()); + testWriter = new TextTestWriter(logger.getPrintStream()); break; case "xml": - writer = new XMLOutputWriter(logger.getOutputStream()); + testWriter = new XMLTestWriter(logger.getOutputStream()); break; case "yaml": - writer = new YAMLOutputWriter(logger.getPrintStream()); + case "yml": + testWriter = new YAMLTestWriter(logger.getPrintStream()); break; } } + respWriter = new ResponseWriter(logger.getPrintStream()); //do action if (cli.hasOption("export")) { @@ -351,7 +355,7 @@ public class ECTester { sent.add(export); for (Response r : sent) { - writer.outputResponse(r); + respWriter.outputResponse(r); } EC_Params exported = new EC_Params(domain, export.getParams()); @@ -425,10 +429,10 @@ public class ECTester { switch (cfg.testSuite) { case "default": - suite = new DefaultSuite(dataStore, cfg, writer); + suite = new DefaultSuite(dataStore, cfg); break; case "test-vectors": - suite = new TestVectorSuite(dataStore, cfg, writer); + suite = new TestVectorSuite(dataStore, cfg); break; default: // These tests are dangerous, prompt before them. @@ -438,7 +442,7 @@ public class ECTester { System.out.print("Do you want to proceed? (y/n): "); Scanner in = new Scanner(System.in); String confirmation = in.nextLine().toLowerCase(); - if (!Arrays.asList("yes","y").contains(confirmation)) { + if (!Arrays.asList("yes", "y").contains(confirmation)) { return; } in.close(); @@ -447,13 +451,13 @@ public class ECTester { switch (cfg.testSuite) { case "wrong": - suite = new WrongCurvesSuite(dataStore, cfg, writer); + suite = new WrongCurvesSuite(dataStore, cfg); break; case "composite": - suite = new CompositeCurvesSuite(dataStore, cfg, writer); + suite = new CompositeCurvesSuite(dataStore, cfg); break; case "invalid": - suite = new InvalidCurvesSuite(dataStore, cfg, writer); + suite = new InvalidCurvesSuite(dataStore, cfg); break; default: System.err.println("Unknown test suite."); @@ -461,7 +465,10 @@ public class ECTester { } break; } - suite.run(cardManager); + + TestRunner runner = new TestRunner(suite, testWriter); + suite.setup(cardManager); + runner.run(); } /** @@ -480,7 +487,7 @@ public class ECTester { prepare.add(curve.send()); for (Response r : prepare) { - writer.outputResponse(r); + respWriter.outputResponse(r); } byte pubkey = (cfg.anyPublicKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; @@ -506,7 +513,7 @@ public class ECTester { Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send(); ecdh.add(perform); for (Response r : ecdh) { - writer.outputResponse(r); + respWriter.outputResponse(r); } if (!perform.successful() || !perform.hasSecret()) { @@ -565,7 +572,7 @@ public class ECTester { prepare.add(curve.send()); for (Response r : prepare) { - writer.outputResponse(r); + respWriter.outputResponse(r); } FileWriter out = null; @@ -583,7 +590,7 @@ public class ECTester { Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, data).send(); ecdsa.add(perform); for (Response r : ecdsa) { - writer.outputResponse(r); + respWriter.outputResponse(r); } if (!perform.successful() || !perform.hasSignature()) { @@ -706,7 +713,7 @@ public class ECTester { } format = cli.getOptionValue("format", "text"); - if (!Arrays.asList("text", "xml", "yaml").contains(format)) { + if (!Arrays.asList("text", "xml", "yaml", "yml").contains(format)) { System.err.println("Wrong output format " + format + "."); return false; } diff --git a/src/cz/crcs/ectester/reader/output/OutputWriter.java b/src/cz/crcs/ectester/reader/output/OutputWriter.java deleted file mode 100644 index 09185b1..0000000 --- a/src/cz/crcs/ectester/reader/output/OutputWriter.java +++ /dev/null @@ -1,18 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; - -import javax.xml.stream.XMLStreamException; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public interface OutputWriter { - void begin(); - void outputResponse(Response r); - void outputTest(Test t); - void end(); -} diff --git a/src/cz/crcs/ectester/reader/output/ResponseWriter.java b/src/cz/crcs/ectester/reader/output/ResponseWriter.java new file mode 100644 index 0000000..120fdba --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/ResponseWriter.java @@ -0,0 +1,39 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.response.Response; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class ResponseWriter { + private PrintStream output; + + public ResponseWriter(PrintStream output) { + this.output = output; + } + + public String responseSuffix(Response r) { + StringBuilder suffix = new StringBuilder(); + for (int j = 0; j < r.getNumSW(); ++j) { + short sw = r.getSW(j); + if (sw != 0) { + suffix.append(" ").append(Util.getSWString(sw)); + } + } + if (suffix.length() == 0) { + suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]"); + } + return String.format("%4d ms : %s", r.getDuration() / 1000000, suffix); + } + + public void outputResponse(Response r) { + String out = ""; + out += String.format("%-70s:", r.getDescription()) + " : "; + out += responseSuffix(r); + output.println(out); + output.flush(); + } +} diff --git a/src/cz/crcs/ectester/reader/output/TeeOutputStream.java b/src/cz/crcs/ectester/reader/output/TeeOutputStream.java index e18d32b..2a1af99 100644 --- a/src/cz/crcs/ectester/reader/output/TeeOutputStream.java +++ b/src/cz/crcs/ectester/reader/output/TeeOutputStream.java @@ -22,14 +22,14 @@ public class TeeOutputStream extends OutputStream { @Override public void flush() throws IOException { - for (OutputStream out :outputs) { + for (OutputStream out : outputs) { out.flush(); } } @Override public void close() throws IOException { - for (OutputStream out :outputs) { + for (OutputStream out : outputs) { out.close(); } } diff --git a/src/cz/crcs/ectester/reader/output/TestWriter.java b/src/cz/crcs/ectester/reader/output/TestWriter.java new file mode 100644 index 0000000..74c76fb --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TestWriter.java @@ -0,0 +1,15 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.TestSuite; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public interface TestWriter { + void begin(TestSuite suite); + + void outputTest(Test t); + + void end(); +} diff --git a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java b/src/cz/crcs/ectester/reader/output/TextOutputWriter.java deleted file mode 100644 index 7f9cdae..0000000 --- a/src/cz/crcs/ectester/reader/output/TextOutputWriter.java +++ /dev/null @@ -1,86 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.Util; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; - -import java.io.PrintStream; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TextOutputWriter implements OutputWriter { - private PrintStream output; - - public TextOutputWriter(PrintStream output) { - this.output = output; - } - - @Override - public void begin() { - } - - private String testPrefix(Test t) { - return String.format("%-4s", t.getResult() == Test.Result.SUCCESS ? "OK" : "NOK"); - } - - private String responseSuffix(Response r) { - StringBuilder suffix = new StringBuilder(); - for (int j = 0; j < r.getNumSW(); ++j) { - short sw = r.getSW(j); - if (sw != 0) { - suffix.append(" ").append(Util.getSWString(sw)); - } - } - if (suffix.length() == 0) { - suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]"); - } - return String.format("%4d ms : %s", r.getDuration() / 1000000, suffix); - } - - @Override - public void outputResponse(Response r) { - String out = ""; - out += String.format("%-70s:", r.getDescription()) + " : "; - out += responseSuffix(r); - output.println(out); - output.flush(); - } - - private String testString(Test t) { - if (!t.hasRun()) - return null; - - StringBuilder out = new StringBuilder(); - if (t instanceof Test.Simple) { - Test.Simple test = (Test.Simple) t; - out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())).append(" : "); - out.append(responseSuffix(test.getResponse())); - } else if (t instanceof Test.Compound) { - Test.Compound test = (Test.Compound) t; - Test[] tests = test.getTests(); - for (int i = 0; i < tests.length; ++i) { - if (i == 0) { - out.append(" /- "); - } else if (i == tests.length - 1) { - out.append(" \\- "); - } else { - out.append(" | "); - } - out.append(testString(tests[i])).append(System.lineSeparator()); - } - out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())); - } - return out.toString(); - } - - @Override - public void outputTest(Test t) { - output.println(testString(t)); - output.flush(); - } - - @Override - public void end() { - } -} diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java new file mode 100644 index 0000000..80c7204 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -0,0 +1,66 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.TestSuite; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TextTestWriter implements TestWriter { + private PrintStream output; + private ResponseWriter respWriter; + + public TextTestWriter(PrintStream output) { + this.output = output; + this.respWriter = new ResponseWriter(output); + } + + @Override + public void begin(TestSuite suite) { + } + + private String testPrefix(Test t) { + return String.format("%-4s", t.getResult() == Test.Result.SUCCESS ? "OK" : "NOK"); + } + + private String testString(Test t) { + if (!t.hasRun()) + return null; + + StringBuilder out = new StringBuilder(); + if (t instanceof Test.Simple) { + Test.Simple test = (Test.Simple) t; + out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())).append(" : "); + out.append(respWriter.responseSuffix(test.getResponse())); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) t; + Test[] tests = test.getTests(); + for (int i = 0; i < tests.length; ++i) { + if (i == 0) { + out.append(" /- "); + } else if (i == tests.length - 1) { + out.append(" \\- "); + } else { + out.append(" | "); + } + out.append(testString(tests[i])).append(System.lineSeparator()); + } + out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())); + } + return out.toString(); + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + output.println(testString(t)); + output.flush(); + } + + @Override + public void end() { + } +} diff --git a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java deleted file mode 100644 index b9f8c8f..0000000 --- a/src/cz/crcs/ectester/reader/output/XMLOutputWriter.java +++ /dev/null @@ -1,118 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.Util; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.*; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import java.io.OutputStream; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class XMLOutputWriter implements OutputWriter { - private OutputStream output; - private Document doc; - private Node root; - - public XMLOutputWriter(OutputStream output) throws ParserConfigurationException { - this.output = output; - this.doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - } - - @Override - public void begin() { - root = doc.createElement("testRun"); - doc.appendChild(root); - } - - private Element responseElement(Response r) { - Element responseElem = doc.createElement("response"); - responseElem.setAttribute("successful", r.successful() ? "true" : "false"); - - Element apdu = doc.createElement("apdu"); - apdu.setTextContent(Util.bytesToHex(r.getAPDU().getBytes())); - responseElem.appendChild(apdu); - - Element naturalSW = doc.createElement("natural-sw"); - naturalSW.setTextContent(String.valueOf(r.getNaturalSW())); - responseElem.appendChild(naturalSW); - - Element sws = doc.createElement("sws"); - for (int i = 0; i < r.getNumSW(); ++i) { - Element sw = doc.createElement("sw"); - sw.setTextContent(String.valueOf(r.getSW(i))); - sws.appendChild(sw); - } - responseElem.appendChild(sws); - - Element duration = doc.createElement("duration"); - duration.setTextContent(String.valueOf(r.getDuration())); - responseElem.appendChild(duration); - - Element description = doc.createElement("desc"); - description.setTextContent(r.getDescription()); - responseElem.appendChild(description); - - return responseElem; - } - - @Override - public void outputResponse(Response r) { - root.appendChild(responseElement(r)); - } - - private Element testElement(Test t) { - Element testElem = doc.createElement("test"); - - if (t instanceof Test.Simple) { - Test.Simple test = (Test.Simple) t; - testElem.setAttribute("type", "simple"); - testElem.appendChild(responseElement(test.getResponse())); - } else if (t instanceof Test.Compound) { - Test.Compound test = (Test.Compound) t; - testElem.setAttribute("type", "compound"); - for (Test innerTest : test.getTests()) { - testElem.appendChild(testElement(innerTest)); - } - } - - Element description = doc.createElement("desc"); - description.setTextContent(t.getDescription()); - testElem.appendChild(description); - - Element result = doc.createElement("result"); - result.setTextContent(t.getResult().toString()); - testElem.appendChild(result); - - return testElem; - } - - @Override - public void outputTest(Test t) { - if (!t.hasRun()) - return; - root.appendChild(testElement(t)); - } - - @Override - public void end() { - try { - DOMSource domSource = new DOMSource(doc); - StreamResult result = new StreamResult(output); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = tf.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.transform(domSource, result); - } catch (TransformerException e) { - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java new file mode 100644 index 0000000..29a97db --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -0,0 +1,117 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.TestSuite; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.OutputStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class XMLTestWriter implements TestWriter { + private OutputStream output; + private Document doc; + private Node root; + + public XMLTestWriter(OutputStream output) throws ParserConfigurationException { + this.output = output; + this.doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } + + @Override + public void begin(TestSuite suite) { + root = doc.createElement("testRun"); + doc.appendChild(root); + } + + private Element responseElement(Response r) { + Element responseElem = doc.createElement("response"); + responseElem.setAttribute("successful", r.successful() ? "true" : "false"); + + Element apdu = doc.createElement("apdu"); + apdu.setTextContent(Util.bytesToHex(r.getAPDU().getBytes())); + responseElem.appendChild(apdu); + + Element naturalSW = doc.createElement("natural-sw"); + naturalSW.setTextContent(String.valueOf(r.getNaturalSW())); + responseElem.appendChild(naturalSW); + + Element sws = doc.createElement("sws"); + for (int i = 0; i < r.getNumSW(); ++i) { + Element sw = doc.createElement("sw"); + sw.setTextContent(String.valueOf(r.getSW(i))); + sws.appendChild(sw); + } + responseElem.appendChild(sws); + + Element duration = doc.createElement("duration"); + duration.setTextContent(String.valueOf(r.getDuration())); + responseElem.appendChild(duration); + + Element description = doc.createElement("desc"); + description.setTextContent(r.getDescription()); + responseElem.appendChild(description); + + return responseElem; + } + + private Element testElement(Test t) { + Element testElem = doc.createElement("test"); + + if (t instanceof Test.Simple) { + Test.Simple test = (Test.Simple) t; + testElem.setAttribute("type", "simple"); + testElem.appendChild(responseElement(test.getResponse())); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) t; + testElem.setAttribute("type", "compound"); + for (Test innerTest : test.getTests()) { + testElem.appendChild(testElement(innerTest)); + } + } + + Element description = doc.createElement("desc"); + description.setTextContent(t.getDescription()); + testElem.appendChild(description); + + Element result = doc.createElement("result"); + result.setTextContent(t.getResult().toString()); + testElem.appendChild(result); + + return testElem; + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + root.appendChild(testElement(t)); + } + + @Override + public void end() { + try { + DOMSource domSource = new DOMSource(doc); + StreamResult result = new StreamResult(output); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.transform(domSource, result); + } catch (TransformerException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java b/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java deleted file mode 100644 index 211bd47..0000000 --- a/src/cz/crcs/ectester/reader/output/YAMLOutputWriter.java +++ /dev/null @@ -1,93 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.reader.Util; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.Test; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; - -import java.io.PrintStream; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class YAMLOutputWriter implements OutputWriter { - private PrintStream output; - private List testRun; - - public YAMLOutputWriter(PrintStream output) { - this.output = output; - } - - @Override - public void begin() { - output.println("---"); - testRun = new LinkedList<>(); - } - - private Map responseObject(Response r) { - Map responseObj = new HashMap<>(); - responseObj.put("successful", r.successful()); - responseObj.put("apdu", Util.bytesToHex(r.getAPDU().getBytes())); - responseObj.put("natural_sw", r.getNaturalSW()); - List sws = new LinkedList<>(); - for (int i = 0; i < r.getNumSW(); ++i) { - sws.add(r.getSW(i)); - } - responseObj.put("sws", sws); - responseObj.put("duration", r.getDuration()); - responseObj.put("desc", r.getDescription()); - return responseObj; - } - - @Override - public void outputResponse(Response r) { - testRun.add(responseObject(r)); - } - - private Map testObject(Test t) { - Map testObj = new HashMap<>(); - - if (t instanceof Test.Simple) { - Test.Simple test = (Test.Simple) t; - testObj.put("type", "simple"); - testObj.put("response", responseObject(test.getResponse())); - } else if (t instanceof Test.Compound) { - Test.Compound test = (Test.Compound) t; - testObj.put("type", "compound"); - List> tests = new LinkedList<>(); - for (Test innerTest : test.getTests()) { - tests.add(testObject(innerTest)); - } - testObj.put("tests", tests); - } - - testObj.put("desc", t.getDescription()); - testObj.put("result", t.getResult().name()); - - return testObj; - } - - @Override - public void outputTest(Test t) { - testRun.add(testObject(t)); - } - - @Override - public void end() { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - Yaml yaml = new Yaml(options); - - Map> result = new HashMap<>(); - result.put("testRun", testRun); - String out = yaml.dump(result); - - output.println(out); - output.println("---"); - } -} diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java new file mode 100644 index 0000000..10d9bb9 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -0,0 +1,92 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.TestSuite; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import java.io.PrintStream; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class YAMLTestWriter implements TestWriter { + private PrintStream output; + private List testRun; + + public YAMLTestWriter(PrintStream output) { + this.output = output; + } + + @Override + public void begin(TestSuite suite) { + output.println("---"); + testRun = new LinkedList<>(); + } + + private Map responseObject(Response r) { + Map responseObj = new HashMap<>(); + responseObj.put("successful", r.successful()); + responseObj.put("apdu", Util.bytesToHex(r.getAPDU().getBytes())); + responseObj.put("natural_sw", r.getNaturalSW()); + List sws = new LinkedList<>(); + for (int i = 0; i < r.getNumSW(); ++i) { + sws.add(r.getSW(i)); + } + responseObj.put("sws", sws); + responseObj.put("duration", r.getDuration()); + responseObj.put("desc", r.getDescription()); + return responseObj; + } + + private Map testObject(Test t) { + Map testObj = new HashMap<>(); + + if (t instanceof Test.Simple) { + Test.Simple test = (Test.Simple) t; + testObj.put("type", "simple"); + testObj.put("response", responseObject(test.getResponse())); + } else if (t instanceof Test.Compound) { + Test.Compound test = (Test.Compound) t; + testObj.put("type", "compound"); + List> tests = new LinkedList<>(); + for (Test innerTest : test.getTests()) { + tests.add(testObject(innerTest)); + } + testObj.put("tests", tests); + } + + testObj.put("desc", t.getDescription()); + testObj.put("result", t.getResult().name()); + + return testObj; + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + testRun.add(testObject(t)); + } + + @Override + public void end() { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setPrettyFlow(true); + Yaml yaml = new Yaml(options); + + Map> result = new HashMap<>(); + result.put("testRun", testRun); + String out = yaml.dump(result); + + output.println(out); + output.println("---"); + } +} diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index 75c6371..76b79de 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -8,7 +8,7 @@ import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Curve; import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.output.OutputWriter; +import cz.crcs.ectester.reader.output.TestWriter; import javacard.security.KeyPair; import javax.smartcardio.CardException; @@ -22,12 +22,12 @@ import java.util.Map; */ public class CompositeCurvesSuite extends TestSuite { - public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "composite"); + public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "composite"); } @Override - public List run(CardMngr cardManager) throws IOException, CardException { + public void setup(CardMngr cardManager) { /* Do the default tests with the public keys set to provided smallorder keys * over composite order curves. Essentially small subgroup attacks. * These should fail, the curves aren't safe so that if the computation with @@ -55,6 +55,5 @@ public class CompositeCurvesSuite extends TestSuite { tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } } - return super.run(cardManager); } } diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index 2024578..de069f9 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -6,25 +6,21 @@ import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.output.OutputWriter; import javacard.security.KeyPair; -import javax.smartcardio.CardException; import java.io.IOException; -import java.util.List; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class DefaultSuite extends TestSuite { - public DefaultSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "default"); + public DefaultSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "default"); } @Override - public List run(CardMngr cardManager) throws IOException, CardException { + public void setup(CardMngr cardManager) throws IOException { tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); if (cfg.namedCurve != null) { if (cfg.primeField) { @@ -57,7 +53,6 @@ public class DefaultSuite extends TestSuite { } } } - return super.run(cardManager); } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java index 20882b6..3b6cb2f 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -8,10 +8,8 @@ import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Curve; import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.output.OutputWriter; import javacard.security.KeyPair; -import javax.smartcardio.CardException; import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; @@ -19,17 +17,16 @@ import java.util.List; import java.util.Map; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class InvalidCurvesSuite extends TestSuite { - public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "invalid"); + public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "invalid"); } @Override - public List run(CardMngr cardManager) throws CardException, IOException { + public void setup(CardMngr cardManager) throws IOException { /* Set original curves (secg/nist/brainpool). Generate local. * Try ECDH with invalid public keys of increasing (or decreasing) order. */ @@ -64,7 +61,5 @@ public class InvalidCurvesSuite extends TestSuite { } tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } - - return super.run(cardManager); } } diff --git a/src/cz/crcs/ectester/reader/test/TestRunner.java b/src/cz/crcs/ectester/reader/test/TestRunner.java new file mode 100644 index 0000000..baab6a8 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/TestRunner.java @@ -0,0 +1,29 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.reader.output.TestWriter; + +import javax.smartcardio.CardException; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TestRunner { + private TestSuite suite; + private TestWriter writer; + + public TestRunner(TestSuite suite, TestWriter writer) { + this.suite = suite; + this.writer = writer; + } + + public void run() throws CardException { + writer.begin(suite); + for (Test t : suite.getTests()) { + if (!t.hasRun()) { + t.run(); + writer.outputTest(t); + } + } + writer.end(); + } +} diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index fde2266..6123a39 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -1,17 +1,13 @@ package cz.crcs.ectester.reader.test; -import static cz.crcs.ectester.reader.test.Test.Result; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; -import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.*; -import cz.crcs.ectester.reader.output.OutputWriter; -import cz.crcs.ectester.reader.response.Response; -import javacard.security.KeyPair; +import cz.crcs.ectester.reader.output.TestWriter; import javax.smartcardio.CardException; import java.io.IOException; @@ -24,28 +20,16 @@ public abstract class TestSuite { EC_Store dataStore; ECTester.Config cfg; - OutputWriter writer; String name; List tests = new LinkedList<>(); - TestSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer, String name) { + TestSuite(EC_Store dataStore, ECTester.Config cfg, String name) { this.dataStore = dataStore; this.cfg = cfg; - this.writer = writer; this.name = name; } - public List run(CardMngr cardManager) throws CardException, IOException { - writer.begin(); - for (Test t : tests) { - if (!t.hasRun()) { - t.run(); - writer.outputTest(t); - } - } - writer.end(); - return tests; - } + public abstract void setup(CardMngr cardManager) throws IOException; public List getTests() { return Collections.unmodifiableList(tests); diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 2098ae3..2a74d41 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -8,28 +8,25 @@ import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.*; -import cz.crcs.ectester.reader.output.OutputWriter; import cz.crcs.ectester.reader.response.Response; import javacard.security.KeyPair; -import javax.smartcardio.CardException; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Map; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class TestVectorSuite extends TestSuite { - public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "test"); + public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "test"); } @Override - public List run(CardMngr cardManager) throws IOException, CardException { + public void setup(CardMngr cardManager) throws IOException { /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. * Do ECDH both ways, export and verify that the result is correct. */ @@ -76,6 +73,5 @@ public class TestVectorSuite extends TestSuite { tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); } - return super.run(cardManager); } } diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 3346b9f..95bbe1e 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -3,7 +3,7 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; -import cz.crcs.ectester.reader.output.OutputWriter; +import cz.crcs.ectester.reader.output.TestWriter; import javacard.security.KeyPair; import javax.smartcardio.CardException; @@ -16,12 +16,12 @@ import java.util.List; */ public class WrongCurvesSuite extends TestSuite { - public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg, OutputWriter writer) { - super(dataStore, cfg, writer, "wrong"); + public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "wrong"); } @Override - public List run(CardMngr cardManager) throws CardException, IOException { + public void setup(CardMngr cardManager) throws IOException { /* Just do the default tests on the wrong curves. * These should generally fail, the curves aren't curves. */ @@ -31,6 +31,5 @@ public class WrongCurvesSuite extends TestSuite { if (cfg.binaryField) { tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); } - return super.run(cardManager); } } -- cgit v1.2.3-70-g09d2 From ca283e0c28ad2050c25f12817db8f8103f1cedc1 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 25 Oct 2017 21:33:31 +0200 Subject: Introduce a Result class, that has a value and a cause. --- src/cz/crcs/ectester/reader/ECTester.java | 10 +-- src/cz/crcs/ectester/reader/Util.java | 10 ++- .../ectester/reader/output/TextTestWriter.java | 4 +- .../crcs/ectester/reader/output/XMLTestWriter.java | 11 ++- .../ectester/reader/output/YAMLTestWriter.java | 3 +- .../ectester/reader/test/CompositeCurvesSuite.java | 21 +++--- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 16 ++--- .../ectester/reader/test/InvalidCurvesSuite.java | 16 ++--- src/cz/crcs/ectester/reader/test/Result.java | 47 +++++++++++++ src/cz/crcs/ectester/reader/test/Test.java | 82 +++++++++++++--------- src/cz/crcs/ectester/reader/test/TestSuite.java | 27 +++---- .../crcs/ectester/reader/test/TestVectorSuite.java | 27 +++---- .../ectester/reader/test/WrongCurvesSuite.java | 6 +- 13 files changed, 177 insertions(+), 103 deletions(-) create mode 100644 src/cz/crcs/ectester/reader/test/Result.java (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 271a8e4..fa71ca6 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -713,8 +713,9 @@ public class ECTester { } format = cli.getOptionValue("format", "text"); - if (!Arrays.asList("text", "xml", "yaml", "yml").contains(format)) { - System.err.println("Wrong output format " + format + "."); + String formats[] = new String[]{"text", "xml", "yaml", "yml"}; + if (!Arrays.asList(formats).contains(format)) { + System.err.println("Wrong output format " + format + ". Should be one of " + Arrays.toString(formats)); return false; } @@ -789,9 +790,8 @@ public class ECTester { testSuite = cli.getOptionValue("test", "default").toLowerCase(); String[] tests = new String[]{"default", "composite", "invalid", "test-vectors", "wrong"}; - List testsList = Arrays.asList(tests); - if (!testsList.contains(testSuite)) { - System.err.println("Unknown test case. Should be one of: " + Arrays.toString(tests)); + if (!Arrays.asList(tests).contains(testSuite)) { + System.err.println("Unknown test suite " + testSuite + ". Should be one of: " + Arrays.toString(tests)); return false; } diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index 754cda3..840f4c5 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -28,15 +28,19 @@ public class Util { array[offset] = (byte) ((value >> 8) & 0xFF); } - public static boolean compareBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) { + public static int diffBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) { for (int i = 0; i < length; ++i) { byte a = one[i + oneOffset]; byte b = other[i + otherOffset]; if (a != b) { - return false; + return i; } } - return true; + return length; + } + + public static boolean compareBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) { + return diffBytes(one, oneOffset, other, otherOffset, length) == length; } public static boolean allValue(byte[] array, byte value) { diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index 80c7204..ca42fba 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.reader.test.Test; +import cz.crcs.ectester.reader.test.Result; import cz.crcs.ectester.reader.test.TestSuite; import java.io.PrintStream; @@ -19,10 +20,11 @@ public class TextTestWriter implements TestWriter { @Override public void begin(TestSuite suite) { + //TODO: output suite.name and suite.description } private String testPrefix(Test t) { - return String.format("%-4s", t.getResult() == Test.Result.SUCCESS ? "OK" : "NOK"); + return String.format("%-4s", t.getResultValue() == Result.Value.SUCCESS ? "OK" : "NOK"); } private String testString(Test t) { diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index 29a97db..c575bb7 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -8,6 +8,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; @@ -23,17 +24,23 @@ import java.io.OutputStream; */ public class XMLTestWriter implements TestWriter { private OutputStream output; + private DocumentBuilder db; private Document doc; private Node root; public XMLTestWriter(OutputStream output) throws ParserConfigurationException { this.output = output; - this.doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + this.db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } @Override public void begin(TestSuite suite) { - root = doc.createElement("testRun"); + doc = db.newDocument(); + Element rootElem = doc.createElement("testSuite"); + rootElem.setAttribute("name", suite.getName()); + rootElem.setAttribute("desc", suite.getDescription()); + + root = rootElem; doc.appendChild(root); } diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index 10d9bb9..6dc5c2d 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -28,6 +28,7 @@ public class YAMLTestWriter implements TestWriter { public void begin(TestSuite suite) { output.println("---"); testRun = new LinkedList<>(); + //TODO: output suite.name and suite.description } private Map responseObject(Response r) { @@ -63,7 +64,7 @@ public class YAMLTestWriter implements TestWriter { } testObj.put("desc", t.getDescription()); - testObj.put("result", t.getResult().name()); + testObj.put("result", t.getResultValue().name()); return testObj; } diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index 76b79de..291d404 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -8,22 +8,17 @@ import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.EC_Curve; import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.output.TestWriter; import javacard.security.KeyPair; -import javax.smartcardio.CardException; -import java.io.IOException; -import java.util.List; import java.util.Map; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class CompositeCurvesSuite extends TestSuite { public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "composite"); + super(dataStore, cfg, "composite", ""); } @Override @@ -44,15 +39,15 @@ public class CompositeCurvesSuite extends TestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.ANY)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.ANY)); - //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); - //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE)); + //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Result.Value.ANY)); + //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index de069f9..722f375 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -16,18 +16,18 @@ import java.io.IOException; public class DefaultSuite extends TestSuite { public DefaultSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "default"); + super(dataStore, cfg, "default", "The default test suite tests basic support of ECDH and ECDSA."); } @Override public void setup(CardMngr cardManager) throws IOException { - tests.add(new Test.Simple(new Command.Support(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Support(cardManager), Result.Value.ANY)); if (cfg.namedCurve != null) { if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); } } else { if (cfg.all) { @@ -56,11 +56,11 @@ public class DefaultSuite extends TestSuite { } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Result.Value.SUCCESS)); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) - tests.add(new Test.Simple(curve, Test.Result.SUCCESS)); - tests.addAll(defaultCurveTests(cardManager, Test.Result.SUCCESS, Test.Result.SUCCESS, Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(curve, Result.Value.SUCCESS)); + tests.addAll(defaultCurveTests(cardManager, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java index 3b6cb2f..e8bf3d7 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -22,7 +22,7 @@ import java.util.Map; public class InvalidCurvesSuite extends TestSuite { public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "invalid"); + super(dataStore, cfg, "invalid", ""); } @Override @@ -51,15 +51,15 @@ public class InvalidCurvesSuite extends TestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.SUCCESS)); for (EC_Key.Public pub : keys) { - // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); - // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE)); + // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.Value.ANY)); + // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Result.Value.FAILURE)); } - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/Result.java b/src/cz/crcs/ectester/reader/test/Result.java new file mode 100644 index 0000000..c6439ef --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/Result.java @@ -0,0 +1,47 @@ +package cz.crcs.ectester.reader.test; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class Result { + + private Value value; + private String cause; + + public Result(Value value) { + this.value = value; + } + + public Result(Value value, String cause) { + this(value); + this.cause = cause; + } + + public Value getValue() { + return value; + } + + public String getCause() { + return cause; + } + + public enum Value { + SUCCESS, + FAILURE, + ANY + } + + public boolean compareTo(Result other) { + if (other == null) { + return false; + } + return value == other.value; + } + + public boolean compareTo(Value other) { + if (other == null) { + return false; + } + return value == other; + } +} diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 1890e94..58da891 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -7,6 +7,8 @@ import javax.smartcardio.CardException; import java.util.function.BiFunction; import java.util.function.Function; +import static cz.crcs.ectester.reader.test.Result.Value; + /** * An abstract test that can be run and has a Result. * @@ -23,6 +25,20 @@ public abstract class Test { return result; } + public Value getResultValue() { + if (!hasRun) { + return null; + } + return result.getValue(); + } + + public String getResultCause() { + if (!hasRun) { + return null; + } + return result.getCause(); + } + public abstract String getDescription(); public boolean hasRun() { @@ -31,16 +47,6 @@ public abstract class Test { public abstract void run() throws CardException; - - /** - * A result of a Test. - */ - public enum Result { - SUCCESS, - FAILURE, - ANY - } - /** * A simple test that runs one Command to get and evaluate one Response * to get a Result and compare it with the expected one. @@ -50,18 +56,24 @@ public abstract class Test { private Command command; private Response response; - public Simple(Command command, Result expected) { + public Simple(Command command, BiFunction callback) { + this.command = command; + this.callback = callback; + } + + public Simple(Command command, Value expected, String ok, String nok) { this(command, (cmd, resp) -> { - if (expected == Result.ANY) - return Result.SUCCESS; - Result respResult = resp.successful() ? Result.SUCCESS : Result.FAILURE; - return respResult == expected ? Result.SUCCESS : Result.FAILURE; + if (expected == Value.ANY) { + return new Result(Value.SUCCESS, ok); + } + Value respResult = resp.successful() ? Value.SUCCESS : Value.FAILURE; + boolean cond = expected == respResult; + return new Result(cond ? Value.SUCCESS : Value.FAILURE, cond ? ok : nok); }); } - public Simple(Command command, BiFunction callback) { - this.command = command; - this.callback = callback; + public Simple(Command command, Value expected) { + this(command, expected, null, null); } public Command getCommand() { @@ -82,9 +94,9 @@ public abstract class Test { result = callback.apply(command, response); } else { if (response.successful()) { - result = Result.SUCCESS; + result = new Result(Value.SUCCESS); } else { - result = Result.FAILURE; + result = new Result(Value.FAILURE); } } hasRun = true; @@ -122,52 +134,52 @@ public abstract class Test { return new Compound(callback, description, tests); } - public static Compound all(Result what, Test... all) { + public static Compound all(Value what, Test... all) { return new Compound((tests) -> { for (Test test : tests) { - if (test.getResult() != what) { - return Result.FAILURE; + if (test.getResultValue() != what) { + return new Result(Value.FAILURE); } } - return Result.SUCCESS; + return new Result(Value.SUCCESS); }, all); } - public static Compound all(Result what, String description, Test... all) { + public static Compound all(Value what, String description, Test... all) { Compound result = Compound.all(what, all); result.setDescription(description); return result; } - public static Compound any(Result what, Test... any) { + public static Compound any(Value what, Test... any) { return new Compound((tests) -> { for (Test test : tests) { - if (test.getResult() == what) { - return Result.SUCCESS; + if (test.getResultValue() == what) { + return new Result(Value.SUCCESS); } } - return Result.FAILURE; + return new Result(Value.FAILURE); }, any); } - public static Compound any(Result what, String description, Test... any) { + public static Compound any(Value what, String description, Test... any) { Compound result = Compound.any(what, any); result.setDescription(description); return result; } - public static Compound mask(Result[] results, Test... masked) { + public static Compound mask(Value[] results, Test... masked) { return new Compound((tests) -> { for (int i = 0; i < results.length; ++i) { - if (results[i] != Result.ANY && results[i] != tests[i].getResult()) { - return Result.FAILURE; + if (results[i] != Value.ANY && results[i] != tests[i].getResultValue()) { + return new Result(Value.FAILURE); } } - return Result.SUCCESS; + return new Result(Value.SUCCESS); }, masked); } - public static Compound mask(Result[] results, String description, Test... masked) { + public static Compound mask(Value[] results, String description, Test... masked) { Compound result = Compound.mask(results, masked); result.setDescription(description); return result; diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 6123a39..3b8476f 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -7,9 +7,7 @@ import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.ec.*; -import cz.crcs.ectester.reader.output.TestWriter; -import javax.smartcardio.CardException; import java.io.IOException; import java.util.*; @@ -17,16 +15,17 @@ import java.util.*; * @author Jan Jancar johny@neuromancer.sk */ public abstract class TestSuite { - EC_Store dataStore; ECTester.Config cfg; String name; + String description; List tests = new LinkedList<>(); - TestSuite(EC_Store dataStore, ECTester.Config cfg, String name) { + TestSuite(EC_Store dataStore, ECTester.Config cfg, String name, String description) { this.dataStore = dataStore; this.cfg = cfg; this.name = name; + this.description = description; } public abstract void setup(CardMngr cardManager) throws IOException; @@ -39,6 +38,10 @@ public abstract class TestSuite { return name; } + public String getDescription() { + return description; + } + /** * @param cardManager cardManager to send APDU through * @param generateExpected expected result of the Generate command @@ -46,16 +49,16 @@ public abstract class TestSuite { * @param ecdsaExpected expected result of the ordinary ECDSA command * @return tests to run */ - List defaultCurveTests(CardMngr cardManager, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdsaExpected) { List tests = new LinkedList<>(); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Test.Result.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Result.Value.FAILURE)); tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return tests; @@ -71,7 +74,7 @@ public abstract class TestSuite { * @param ecdsaExpected expected result of the ordinary ECDSA command * @return tests to run */ - List defaultCategoryTests(CardMngr cardManager, String category, byte field, Test.Result setExpected, Test.Result generateExpected, Test.Result ecdhExpected, Test.Result ecdsaExpected) { + List defaultCategoryTests(CardMngr cardManager, String category, byte field, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdsaExpected) { List tests = new LinkedList<>(); Map curves = dataStore.getObjects(EC_Curve.class, category); if (curves == null) @@ -79,10 +82,10 @@ public abstract class TestSuite { for (Map.Entry entry : curves.entrySet()) { EC_Curve curve = entry.getValue(); if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Test.Result.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Result.Value.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); tests.addAll(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 2a74d41..4a91940 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -22,7 +22,7 @@ import java.util.Map; public class TestVectorSuite extends TestSuite { public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "test"); + super(dataStore, cfg, "test", ""); } @Override @@ -55,22 +55,25 @@ public class TestVectorSuite extends TestSuite { } List testVector = new LinkedList<>(); - testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); - //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); + //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Result.Value.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Result.Value.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Result.Value.SUCCESS)); testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> { Response.ECDH dh = (Response.ECDH) response; - if (!dh.successful() || !dh.hasSecret()) - return Test.Result.FAILURE; + 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 (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { - return Test.Result.FAILURE; + int firstDiff = Util.diffBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength()); + return new Result(Result.Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); } - return Test.Result.SUCCESS; + return new Result(Result.Value.SUCCESS); })); - tests.add(Test.Compound.all(Test.Result.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Test.Result.ANY)); + tests.add(Test.Compound.all(Result.Value.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 95bbe1e..307a16a 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -17,7 +17,7 @@ import java.util.List; public class WrongCurvesSuite extends TestSuite { public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "wrong"); + super(dataStore, cfg, "wrong", ""); } @Override @@ -26,10 +26,10 @@ public class WrongCurvesSuite extends TestSuite { * These should generally fail, the curves aren't curves. */ if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE, Test.Result.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE)); } } } -- cgit v1.2.3-70-g09d2 From ed0c5467c3fc16ca93aeab0cf06a5046915afdd6 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 26 Oct 2017 00:17:07 +0200 Subject: Add some more compound tests and suite descriptions. --- src/cz/crcs/ectester/reader/output/XMLTestWriter.java | 8 +++++++- src/cz/crcs/ectester/reader/output/YAMLTestWriter.java | 5 ++++- src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java | 9 +++------ src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java | 9 +++++---- src/cz/crcs/ectester/reader/test/Test.java | 12 ++++++------ src/cz/crcs/ectester/reader/test/TestVectorSuite.java | 2 +- src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java | 6 +----- 7 files changed, 27 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index c575bb7..d5902ae 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -95,7 +95,12 @@ public class XMLTestWriter implements TestWriter { testElem.appendChild(description); Element result = doc.createElement("result"); - result.setTextContent(t.getResult().toString()); + Element value = doc.createElement("value"); + value.setTextContent(t.getResultValue().name()); + Element cause = doc.createElement("cause"); + cause.setTextContent(t.getResultCause()); + result.appendChild(value); + result.appendChild(cause); testElem.appendChild(result); return testElem; @@ -116,6 +121,7 @@ public class XMLTestWriter implements TestWriter { TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); transformer.transform(domSource, result); } catch (TransformerException e) { e.printStackTrace(); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index 6dc5c2d..d2e3ff8 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -64,7 +64,10 @@ public class YAMLTestWriter implements TestWriter { } testObj.put("desc", t.getDescription()); - testObj.put("result", t.getResultValue().name()); + Map result = new HashMap<>(); + result.put("value", t.getResultValue().name()); + result.put("cause", t.getResultCause()); + testObj.put("result", result); return testObj; } diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index 291d404..c777a77 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -18,7 +18,7 @@ import java.util.Map; public class CompositeCurvesSuite extends TestSuite { public CompositeCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "composite", ""); + super(dataStore, cfg, "composite", "The composite suite tests ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); } @Override @@ -42,11 +42,8 @@ public class CompositeCurvesSuite extends TestSuite { tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.ANY)); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.ANY)); - - //tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Result.Value.ANY)); - //tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Result.Value.FAILURE)); - + Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()); + tests.add(new Test.Simple(ecdhCommand, Result.Value.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(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java index e8bf3d7..229a5a3 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -22,7 +22,7 @@ import java.util.Map; public class InvalidCurvesSuite extends TestSuite { public InvalidCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "invalid", ""); + super(dataStore, cfg, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); } @Override @@ -54,11 +54,12 @@ public class InvalidCurvesSuite extends TestSuite { tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.SUCCESS)); + List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - // tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.Value.ANY)); - // tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Result.Value.FAILURE)); + Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()); + ecdhTests.add(new Test.Simple(ecdhCommand, Result.Value.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); } + tests.add(Test.Compound.all(Result.Value.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 58da891..3848df2 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -138,10 +138,10 @@ public abstract class Test { return new Compound((tests) -> { for (Test test : tests) { if (test.getResultValue() != what) { - return new Result(Value.FAILURE); + return new Result(Value.FAILURE, "At least one of the sub-tests did not have the expected result."); } } - return new Result(Value.SUCCESS); + return new Result(Value.SUCCESS, "All sub-tests had the expected result."); }, all); } @@ -155,10 +155,10 @@ public abstract class Test { return new Compound((tests) -> { for (Test test : tests) { if (test.getResultValue() == what) { - return new Result(Value.SUCCESS); + return new Result(Value.SUCCESS, "At least one of the sub-tests did have the expected result."); } } - return new Result(Value.FAILURE); + return new Result(Value.FAILURE, "None of the sub-tests had the expected result."); }, any); } @@ -172,10 +172,10 @@ public abstract class Test { return new Compound((tests) -> { for (int i = 0; i < results.length; ++i) { if (results[i] != Value.ANY && results[i] != tests[i].getResultValue()) { - return new Result(Value.FAILURE); + return new Result(Value.FAILURE, "At least one of the sub-tests did not match the result mask."); } } - return new Result(Value.SUCCESS); + return new Result(Value.SUCCESS, "All sub-tests matched the expected mask."); }, masked); } diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 4a91940..7a2767e 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -22,7 +22,7 @@ import java.util.Map; public class TestVectorSuite extends TestSuite { public TestVectorSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "test", ""); + super(dataStore, cfg, "test", "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); } @Override diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 307a16a..76fc9d9 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -3,21 +3,17 @@ package cz.crcs.ectester.reader.test; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; -import cz.crcs.ectester.reader.output.TestWriter; import javacard.security.KeyPair; -import javax.smartcardio.CardException; import java.io.IOException; -import java.util.List; /** - * * @author Jan Jancar johny@neuromancer.sk */ public class WrongCurvesSuite extends TestSuite { public WrongCurvesSuite(EC_Store dataStore, ECTester.Config cfg) { - super(dataStore, cfg, "wrong", ""); + super(dataStore, cfg, "wrong", "The wrong curve suite tests whether the card rejects domain parameters which are not curves."); } @Override -- cgit v1.2.3-70-g09d2 From d7af85c327e239f637ffd7e2246fc7e365b6e075 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 26 Oct 2017 00:23:50 +0200 Subject: Update README and help. --- README.md | 5 +++++ src/cz/crcs/ectester/reader/ECTester.java | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/README.md b/README.md index 4bae53b..82cb645 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,15 @@ See `java -jar ECTester.jar -h` for more. -o,--output Output into file . -l,--log Log output into file [log_file]. -v,--verbose Turn on verbose logging. + --format Output format to use. -f,--fresh Generate fresh keys (set domain parameters before every generation). -s,--simulate Simulate a card with jcardsim instead of using a terminal. + -y,--yes Accept all warnings and prompts. + -ka,--ka-type Set KeyAgreement object [type], + corresponds to JC.KeyAgreement + constants. ``` ### Actions diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index fa71ca6..413acae 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -232,11 +232,13 @@ public class ECTester { * * -i / --input * -o / --output + * --format * -l / --log [log_file] * * -f / --fresh * -s / --simulate * -y / --yes + * -ka/ --ka-type */ OptionGroup actions = new OptionGroup(); actions.setRequired(true); @@ -284,7 +286,7 @@ public class ECTester { opts.addOption(Option.builder("o").longOpt("output").desc("Output into file .").hasArg().argName("output_file").build()); opts.addOption(Option.builder("l").longOpt("log").desc("Log output into file [log_file].").hasArg().argName("log_file").optionalArg(true).build()); opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build()); - opts.addOption(Option.builder().longOpt("format").desc("Output format to use.").hasArg().argName("format").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("f").longOpt("fresh").desc("Generate fresh keys (set domain parameters before every generation).").build()); opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); -- cgit v1.2.3-70-g09d2 From 58df557ecb0dff70c10dc4c53b000ff0cc6490ce Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 27 Oct 2017 16:53:49 +0200 Subject: Specify Response.support string better. --- src/cz/crcs/ectester/reader/response/Response.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 962261e..1906811 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -546,7 +546,7 @@ public abstract class Response { @Override public String getDescription() { - return "Support of ECDH, ECDHC, ECDSA"; + return "Support of ECDH, ECDHC, ECDSA allocation"; } } } -- cgit v1.2.3-70-g09d2 From 567695b16aef0f0706f46f0a87c83baae808b47e Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 31 Oct 2017 21:18:09 +0100 Subject: Add compound test to default tests. --- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 7 +- src/cz/crcs/ectester/reader/test/TestSuite.java | 74 ++++++++++++++++------ .../ectester/reader/test/WrongCurvesSuite.java | 5 +- 3 files changed, 63 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index 722f375..8fea661 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -23,11 +23,12 @@ public class DefaultSuite extends TestSuite { public void setup(CardMngr cardManager) throws IOException { tests.add(new Test.Simple(new Command.Support(cardManager), Result.Value.ANY)); if (cfg.namedCurve != null) { + String desc = "Default tests over the " + cfg.namedCurve + " curve category."; if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, desc)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, desc)); } } else { if (cfg.all) { @@ -60,7 +61,7 @@ public class DefaultSuite extends TestSuite { Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) tests.add(new Test.Simple(curve, Result.Value.SUCCESS)); - tests.addAll(defaultCurveTests(cardManager, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS)); + tests.add(defaultCurveTests(cardManager, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, "Default tests.")); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index 3b8476f..c0e8e91 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -6,10 +6,14 @@ import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTester; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.ec.*; +import cz.crcs.ectester.reader.ec.EC_Curve; import java.io.IOException; -import java.util.*; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; /** * @author Jan Jancar johny@neuromancer.sk @@ -43,13 +47,15 @@ public abstract class TestSuite { } /** - * @param cardManager cardManager to send APDU through - * @param generateExpected expected result of the Generate command - * @param ecdhExpected expected result of the ordinary ECDH command - * @param ecdsaExpected expected result of the ordinary ECDSA command - * @return tests to run + * @param cardManager cardManager to send APDU through + * @param generateExpected expected result of the Generate command + * @param ecdhExpected expected result of the ordinary ECDH command + * @param ecdhCompressExpected expected result of ECDH with a compressed point + * @param ecdsaExpected expected result of the ordinary ECDSA command + * @param description compound test description + * @return test to run */ - List defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdsaExpected) { + Test defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressExpected, Result.Value ecdsaExpected, String description) { List tests = new LinkedList<>(); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); @@ -61,20 +67,52 @@ public abstract class TestSuite { tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Result.Value.FAILURE)); tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); - return tests; + return Test.Compound.function((testArray) -> { + Function shouldHave = (expected) -> { + switch (expected) { + case SUCCESS: + return "been successful"; + case FAILURE: + return "failed"; + case ANY: + default: + return ""; + } + }; + + for (int i = 0; i < testArray.length; ++i) { + Test t = testArray[i]; + if (t.getResultValue() != Result.Value.SUCCESS) { + if (i == 0) { // generate + return new Result(Result.Value.FAILURE, "The generation of a key should have " + shouldHave.apply(generateExpected) + ", but it did not."); + } else if (i == 2) { // ecdh compress + return new Result(Result.Value.FAILURE, "The ECDH should have " + shouldHave.apply(ecdhExpected) + ", but it did not."); + } else if (i == 1) { // ecdh normal + return new Result(Result.Value.FAILURE, "The ECDH of a compressed point should have " + shouldHave.apply(ecdhCompressExpected) + ", but it did not."); + } else if (i <= 6) { // ecdh wrong, should fail + return new Result(Result.Value.FAILURE, "The ECDH of a corrupted point should have failed, but it dit not."); + } else { // ecdsa + return new Result(Result.Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); + } + } + } + return new Result(Result.Value.SUCCESS); + }, description, tests.toArray(new Test[0])); } /** - * @param cardManager cardManager to send APDU through - * @param category category to test - * @param field field to test (KeyPair.ALG_EC_FP || KeyPair.ALG_EC_F2M) - * @param setExpected expected result of the Set (curve) command - * @param generateExpected expected result of the Generate command - * @param ecdhExpected expected result of the ordinary ECDH command - * @param ecdsaExpected expected result of the ordinary ECDSA command + * @param cardManager cardManager to send APDU through + * @param category category to test + * @param field field to test (KeyPair.ALG_EC_FP || KeyPair.ALG_EC_F2M) + * @param setExpected expected result of the Set (curve) command + * @param generateExpected expected result of the Generate command + * @param ecdhExpected expected result of the ordinary ECDH command + * @param ecdhCompressedExpected + * @param ecdsaExpected expected result of the ordinary ECDSA command + * @param description compound test description * @return tests to run */ - List defaultCategoryTests(CardMngr cardManager, String category, byte field, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdsaExpected) { + List defaultCategoryTests(CardMngr cardManager, String category, byte field, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressedExpected, Result.Value ecdsaExpected, String description) { List tests = new LinkedList<>(); Map curves = dataStore.getObjects(EC_Curve.class, category); if (curves == null) @@ -84,7 +122,7 @@ public abstract class TestSuite { if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Result.Value.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); - tests.addAll(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdsaExpected)); + tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 76fc9d9..20cb405 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -21,11 +21,12 @@ public class WrongCurvesSuite extends TestSuite { /* Just do the default tests on the wrong curves. * These should generally fail, the curves aren't curves. */ + String desc = "Default tests over wrong curve params."; if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, desc)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, desc)); } } } -- cgit v1.2.3-70-g09d2 From d789fc6f20d1f65a09804ac473c79a40cea6fedd Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 31 Oct 2017 23:57:07 +0100 Subject: Fix response output. --- src/cz/crcs/ectester/reader/ECTester.java | 10 +++++----- src/cz/crcs/ectester/reader/output/ResponseWriter.java | 2 +- src/cz/crcs/ectester/reader/output/TextTestWriter.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 413acae..3de6094 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -387,7 +387,7 @@ public class ECTester { while (generated < cfg.generateAmount || cfg.generateAmount == 0) { if ((cfg.fresh || generated == 0) && curve != null) { Response fresh = curve.send(); - logger.println(fresh.toString()); + respWriter.outputResponse(fresh); } Command.Generate generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL); @@ -405,7 +405,7 @@ public class ECTester { break; } } - logger.println(response.toString()); + respWriter.outputResponse(response); String pub = Util.bytesToHex(export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_W), false); String priv = Util.bytesToHex(export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S), false); @@ -415,7 +415,7 @@ public class ECTester { generated++; } Response cleanup = new Command.Cleanup(cardManager).send(); - logger.println(cleanup.toString()); + respWriter.outputResponse(cleanup); keysFile.close(); } @@ -535,7 +535,7 @@ public class ECTester { ++done; } Response cleanup = new Command.Cleanup(cardManager).send(); - logger.println(cleanup.toString()); + respWriter.outputResponse(cleanup); if (out != null) out.close(); @@ -612,7 +612,7 @@ public class ECTester { ++done; } Response cleanup = new Command.Cleanup(cardManager).send(); - logger.println(cleanup.toString()); + respWriter.outputResponse(cleanup); if (out != null) out.close(); diff --git a/src/cz/crcs/ectester/reader/output/ResponseWriter.java b/src/cz/crcs/ectester/reader/output/ResponseWriter.java index 120fdba..ee5d652 100644 --- a/src/cz/crcs/ectester/reader/output/ResponseWriter.java +++ b/src/cz/crcs/ectester/reader/output/ResponseWriter.java @@ -31,7 +31,7 @@ public class ResponseWriter { public void outputResponse(Response r) { String out = ""; - out += String.format("%-70s:", r.getDescription()) + " : "; + out += String.format("%-70s", r.getDescription()) + " : "; out += responseSuffix(r); output.println(out); output.flush(); diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index ca42fba..a5cb526 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -49,7 +49,7 @@ public class TextTestWriter implements TestWriter { } out.append(testString(tests[i])).append(System.lineSeparator()); } - out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())); + out.append(String.format("%-70s", testPrefix(t) + " : " + test.getDescription())); } return out.toString(); } -- cgit v1.2.3-70-g09d2 From ca92d2e5237ce3efcfc90f22036b72a2a34679ac Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 1 Nov 2017 21:50:33 +0100 Subject: Add default test scripts. --- !uploader/ectester.cap | Bin 16008 -> 16008 bytes build.xml | 4 +++ dist/ECTester.jar | Bin 726928 -> 802635 bytes dist/ectester.bat | 34 ++++++++++++++++++++++ dist/ectester.sh | 45 ++++++++++++++++++++++++++++++ src/cz/crcs/ectester/scripts/ectester.bat | 34 ++++++++++++++++++++++ src/cz/crcs/ectester/scripts/ectester.sh | 45 ++++++++++++++++++++++++++++++ 7 files changed, 162 insertions(+) create mode 100644 dist/ectester.bat create mode 100755 dist/ectester.sh create mode 100644 src/cz/crcs/ectester/scripts/ectester.bat create mode 100755 src/cz/crcs/ectester/scripts/ectester.sh (limited to 'src') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index 3b9e650..e3c1dc5 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/build.xml b/build.xml index 1fd4fcd..9263272 100644 --- a/build.xml +++ b/build.xml @@ -92,4 +92,8 @@ --> + + + + diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 8195c6f..90d9b9a 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/dist/ectester.bat b/dist/ectester.bat new file mode 100644 index 0000000..e20b855 --- /dev/null +++ b/dist/ectester.bat @@ -0,0 +1,34 @@ +@ECHO OFF +SETLOCAL enabledelayedexpansion + +SET n=0 +:loop +IF NOT "%1"=="" ( + IF "%1"=="--dangerous" ( + SET dangerous=1 + ) ELSE ( + SET positional[!n!]=%1 + SET /A n+=1 + ) + SHIFT + GOTO :loop +) + +IF NOT "%n%"=="1" ( + ECHO "One argument expected:" + ECHO " ./ectester.bar [--dangerous] CARD_NAME" +) + +SET card=!positional[%%0]! + +SET tests="default test-vectors" +java -jar ECTester.jar -t default -a --format yaml -l %card%.default +java -jar ECTester.jar -t test-vectors -a --format yaml -l %card%.test-vectors +IF "%dangerous%"=="1" ( + SET tests=%tests% "invalid wrong composite" + java -jar ECTester.jar -t invalid -a --format yaml -l %card%.invalid + java -jar ECTester.jar -t wrong -a --format yaml -l %card%.wrong + java -jar ECTester.jar -t composite -a --format yaml -l %card%.composite +) + +zip %card%.zip %tests% diff --git a/dist/ectester.sh b/dist/ectester.sh new file mode 100755 index 0000000..0de1bc3 --- /dev/null +++ b/dist/ectester.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +dangerous="0" + +positional=() +while [[ $# -gt 0 ]] +do + +key="$1" +case $key in + --dangerous) + dangerous=1 + shift + ;; + *) + positional+=("$1") + shift + ;; +esac +done +set -- "${positional[@]}" + +if [[ $# -ne 1 ]]; then + echo "One argument expected:" >&2 + echo " ./ectester.sh [--dangerous] CARD_NAME" >&2 + exit 1 +fi + +declare -a tests=("default" "test-vectors") +if [[ "$dangerous" == "1" ]]; then + tests+=("invalid" "wrong" "composite") +fi + +declare -a files=() +for i in $(seq 0 $((${#tests[@]} - 1))); do + test="${tests[$i]}" + java -jar ECTester.jar -t ${test} -a --format yaml -l ${1}.${test} + files+=(${1}.$test) +done + +if command -v tar 2>&1 >/dev/null; then + tar -czvf ${1}.tar.gz ${files[*]} +elif command -v zip 2>&1 >/dev/null; then + zip ${1}.zip ${files[*]} +fi \ No newline at end of file diff --git a/src/cz/crcs/ectester/scripts/ectester.bat b/src/cz/crcs/ectester/scripts/ectester.bat new file mode 100644 index 0000000..e20b855 --- /dev/null +++ b/src/cz/crcs/ectester/scripts/ectester.bat @@ -0,0 +1,34 @@ +@ECHO OFF +SETLOCAL enabledelayedexpansion + +SET n=0 +:loop +IF NOT "%1"=="" ( + IF "%1"=="--dangerous" ( + SET dangerous=1 + ) ELSE ( + SET positional[!n!]=%1 + SET /A n+=1 + ) + SHIFT + GOTO :loop +) + +IF NOT "%n%"=="1" ( + ECHO "One argument expected:" + ECHO " ./ectester.bar [--dangerous] CARD_NAME" +) + +SET card=!positional[%%0]! + +SET tests="default test-vectors" +java -jar ECTester.jar -t default -a --format yaml -l %card%.default +java -jar ECTester.jar -t test-vectors -a --format yaml -l %card%.test-vectors +IF "%dangerous%"=="1" ( + SET tests=%tests% "invalid wrong composite" + java -jar ECTester.jar -t invalid -a --format yaml -l %card%.invalid + java -jar ECTester.jar -t wrong -a --format yaml -l %card%.wrong + java -jar ECTester.jar -t composite -a --format yaml -l %card%.composite +) + +zip %card%.zip %tests% diff --git a/src/cz/crcs/ectester/scripts/ectester.sh b/src/cz/crcs/ectester/scripts/ectester.sh new file mode 100755 index 0000000..0de1bc3 --- /dev/null +++ b/src/cz/crcs/ectester/scripts/ectester.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +dangerous="0" + +positional=() +while [[ $# -gt 0 ]] +do + +key="$1" +case $key in + --dangerous) + dangerous=1 + shift + ;; + *) + positional+=("$1") + shift + ;; +esac +done +set -- "${positional[@]}" + +if [[ $# -ne 1 ]]; then + echo "One argument expected:" >&2 + echo " ./ectester.sh [--dangerous] CARD_NAME" >&2 + exit 1 +fi + +declare -a tests=("default" "test-vectors") +if [[ "$dangerous" == "1" ]]; then + tests+=("invalid" "wrong" "composite") +fi + +declare -a files=() +for i in $(seq 0 $((${#tests[@]} - 1))); do + test="${tests[$i]}" + java -jar ECTester.jar -t ${test} -a --format yaml -l ${1}.${test} + files+=(${1}.$test) +done + +if command -v tar 2>&1 >/dev/null; then + tar -czvf ${1}.tar.gz ${files[*]} +elif command -v zip 2>&1 >/dev/null; then + zip ${1}.zip ${files[*]} +fi \ No newline at end of file -- cgit v1.2.3-70-g09d2 From d776f70f6b913b65ed1c40a9020868d85edf7d9f Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 1 Nov 2017 22:05:56 +0100 Subject: Add output of commands to test-suite YAML and XML output. --- .../ectester/reader/output/TextTestWriter.java | 3 ++- .../crcs/ectester/reader/output/XMLTestWriter.java | 12 ++++++++++ .../ectester/reader/output/YAMLTestWriter.java | 26 +++++++++++++++++----- 3 files changed, 35 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index a5cb526..dedefe6 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -20,7 +20,8 @@ public class TextTestWriter implements TestWriter { @Override public void begin(TestSuite suite) { - //TODO: output suite.name and suite.description + output.println("=== Running test suite: " + suite.getName() + " ==="); + output.println("=== " + suite.getDescription()); } private String testPrefix(Test t) { diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index d5902ae..b4accdd 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.Test; import cz.crcs.ectester.reader.test.TestSuite; @@ -44,6 +45,16 @@ public class XMLTestWriter implements TestWriter { doc.appendChild(root); } + private Element commandElement(Command c) { + Element commandElem = doc.createElement("command"); + + Element apdu = doc.createElement("apdu"); + apdu.setTextContent(Util.bytesToHex(c.getAPDU().getBytes())); + commandElem.appendChild(apdu); + + return commandElem; + } + private Element responseElement(Response r) { Element responseElem = doc.createElement("response"); responseElem.setAttribute("successful", r.successful() ? "true" : "false"); @@ -81,6 +92,7 @@ public class XMLTestWriter implements TestWriter { if (t instanceof Test.Simple) { Test.Simple test = (Test.Simple) t; testElem.setAttribute("type", "simple"); + testElem.appendChild(commandElement(test.getCommand())); testElem.appendChild(responseElement(test.getResponse())); } else if (t instanceof Test.Compound) { Test.Compound test = (Test.Compound) t; diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index d2e3ff8..93e2b45 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.Test; import cz.crcs.ectester.reader.test.TestSuite; @@ -18,7 +19,9 @@ import java.util.Map; */ public class YAMLTestWriter implements TestWriter { private PrintStream output; - private List testRun; + private Map testRun; + private Map testSuite; + private List tests; public YAMLTestWriter(PrintStream output) { this.output = output; @@ -27,8 +30,20 @@ public class YAMLTestWriter implements TestWriter { @Override public void begin(TestSuite suite) { output.println("---"); - testRun = new LinkedList<>(); - //TODO: output suite.name and suite.description + testRun = new HashMap<>(); + testSuite = new HashMap<>(); + tests = new LinkedList<>(); + testSuite.put("name", suite.getName()); + testSuite.put("desc", suite.getDescription()); + + testRun.put("suite", testSuite); + testRun.put("tests", tests); + } + + private Map commandObject(Command c) { + Map commandObj = new HashMap<>(); + commandObj.put("apdu", Util.bytesToHex(c.getAPDU().getBytes())); + return commandObj; } private Map responseObject(Response r) { @@ -52,6 +67,7 @@ public class YAMLTestWriter implements TestWriter { if (t instanceof Test.Simple) { Test.Simple test = (Test.Simple) t; testObj.put("type", "simple"); + testObj.put("command", commandObject(test.getCommand())); testObj.put("response", responseObject(test.getResponse())); } else if (t instanceof Test.Compound) { Test.Compound test = (Test.Compound) t; @@ -76,7 +92,7 @@ public class YAMLTestWriter implements TestWriter { public void outputTest(Test t) { if (!t.hasRun()) return; - testRun.add(testObject(t)); + tests.add(testObject(t)); } @Override @@ -86,7 +102,7 @@ public class YAMLTestWriter implements TestWriter { options.setPrettyFlow(true); Yaml yaml = new Yaml(options); - Map> result = new HashMap<>(); + Map result = new HashMap<>(); result.put("testRun", testRun); String out = yaml.dump(result); -- cgit v1.2.3-70-g09d2 From daaa7abd91ff8ae12e0b1835045489acbda0539f Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 5 Nov 2017 16:48:30 +0100 Subject: Implement Result.ExpectedValue to add more logic to test evaluation. - Introduces a new enum Result.ExpectedValue, which is used to signify what Test results are expected. - Changes the Result.Value enum to contain information about what was expected. It gains more values: - UXSUCCESS -> Unexpected success. - XFAILURE -> Expected failure. The values SUCCESS and XFAILURE are the OK, values. - Creates a hierarchy of evaluating Responses, Simple tests and Compoung tests. Simple test evaluates the OK property of the response object (using .successfull() method) and again exposes its OK property which depends on the tests ExpectedValue and the response success. Compound test evaluates the OK property of the Simple tests it contains (using the .ok() method) and again exposes its OK property which depends on the concrete Compound test variant, but involves some ExpectedValues and the success of the individual Simple tests it contains. --- .../ectester/reader/output/ResponseWriter.java | 2 +- .../ectester/reader/output/TextTestWriter.java | 50 +++++++++++++++------- .../crcs/ectester/reader/output/XMLTestWriter.java | 3 ++ .../ectester/reader/output/YAMLTestWriter.java | 3 +- .../ectester/reader/test/CompositeCurvesSuite.java | 12 +++--- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 16 ++++--- .../ectester/reader/test/InvalidCurvesSuite.java | 14 +++--- src/cz/crcs/ectester/reader/test/Result.java | 33 ++++++++++++++ src/cz/crcs/ectester/reader/test/Test.java | 38 ++++++++-------- src/cz/crcs/ectester/reader/test/TestSuite.java | 39 +++++++++-------- .../crcs/ectester/reader/test/TestVectorSuite.java | 25 ++++++----- .../ectester/reader/test/WrongCurvesSuite.java | 6 ++- 12 files changed, 157 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/ResponseWriter.java b/src/cz/crcs/ectester/reader/output/ResponseWriter.java index ee5d652..0f932e7 100644 --- a/src/cz/crcs/ectester/reader/output/ResponseWriter.java +++ b/src/cz/crcs/ectester/reader/output/ResponseWriter.java @@ -26,7 +26,7 @@ public class ResponseWriter { if (suffix.length() == 0) { suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]"); } - return String.format("%4d ms : %s", r.getDuration() / 1000000, suffix); + return String.format("%4d ms ┃ %s", r.getDuration() / 1000000, suffix); } public void outputResponse(Response r) { diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index dedefe6..d697761 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -1,7 +1,6 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.reader.test.Test; -import cz.crcs.ectester.reader.test.Result; import cz.crcs.ectester.reader.test.TestSuite; import java.io.PrintStream; @@ -13,6 +12,8 @@ public class TextTestWriter implements TestWriter { private PrintStream output; private ResponseWriter respWriter; + public static int BASE_WIDTH = 72; + public TextTestWriter(PrintStream output) { this.output = output; this.respWriter = new ResponseWriter(output); @@ -24,34 +25,51 @@ public class TextTestWriter implements TestWriter { output.println("=== " + suite.getDescription()); } - private String testPrefix(Test t) { - return String.format("%-4s", t.getResultValue() == Result.Value.SUCCESS ? "OK" : "NOK"); - } - private String testString(Test t) { - if (!t.hasRun()) + private String testString(Test t, int offset) { + if (!t.hasRun()) { return null; + } StringBuilder out = new StringBuilder(); if (t instanceof Test.Simple) { Test.Simple test = (Test.Simple) t; - out.append(String.format("%-70s:", testPrefix(t) + " : " + test.getDescription())).append(" : "); + out.append(test.ok() ? "OK " : "NOK "); + out.append("━ "); + int width = BASE_WIDTH - (offset + out.length()); + String widthSpec = "%-" + String.valueOf(width) + "s"; + out.append(String.format(widthSpec, t.getDescription())); + out.append(" ┃ "); + out.append(String.format("%-9s", test.getResultValue().name())); + out.append(" ┃ "); out.append(respWriter.responseSuffix(test.getResponse())); - } else if (t instanceof Test.Compound) { + } else { + out.append(System.lineSeparator()); Test.Compound test = (Test.Compound) t; + out.append(test.ok() ? "OK " : "NOK "); + out.append("┳ "); + int width = BASE_WIDTH - (offset + out.length()); + String widthSpec = "%-" + String.valueOf(width) + "s"; + out.append(String.format(widthSpec, t.getDescription())); + out.append(" ┃ "); + out.append(String.format("%-9s", test.getResultValue().name())); + out.append(" ┃ "); + out.append(test.getResultCause()); + out.append(System.lineSeparator()); Test[] tests = test.getTests(); for (int i = 0; i < tests.length; ++i) { - if (i == 0) { - out.append(" /- "); - } else if (i == tests.length - 1) { - out.append(" \\- "); + if (i == tests.length - 1) { + out.append(" ┗ "); } else { - out.append(" | "); + out.append(" ┣ "); + } + out.append(testString(tests[i], offset + 6)); + if (i != tests.length - 1) { + out.append(System.lineSeparator()); } - out.append(testString(tests[i])).append(System.lineSeparator()); } - out.append(String.format("%-70s", testPrefix(t) + " : " + test.getDescription())); } + return out.toString(); } @@ -59,7 +77,7 @@ public class TextTestWriter implements TestWriter { public void outputTest(Test t) { if (!t.hasRun()) return; - output.println(testString(t)); + output.println(testString(t, 0)); output.flush(); } diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index b4accdd..709d215 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -107,10 +107,13 @@ public class XMLTestWriter implements TestWriter { testElem.appendChild(description); Element result = doc.createElement("result"); + Element ok = doc.createElement("ok"); + ok.setTextContent(String.valueOf(t.ok())); Element value = doc.createElement("value"); value.setTextContent(t.getResultValue().name()); Element cause = doc.createElement("cause"); cause.setTextContent(t.getResultCause()); + result.appendChild(ok); result.appendChild(value); result.appendChild(cause); testElem.appendChild(result); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index 93e2b45..f0dcd3a 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -80,7 +80,8 @@ public class YAMLTestWriter implements TestWriter { } testObj.put("desc", t.getDescription()); - Map result = new HashMap<>(); + Map result = new HashMap<>(); + result.put("ok", t.ok()); result.put("value", t.getResultValue().name()); result.put("cause", t.getResultCause()); testObj.put("result", result); diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index c777a77..8e7ca31 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -12,6 +12,8 @@ import javacard.security.KeyPair; import java.util.Map; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -39,12 +41,12 @@ public class CompositeCurvesSuite extends TestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.ANY)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.ANY)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()); - tests.add(new Test.Simple(ecdhCommand, Result.Value.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(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(new Test.Simple(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(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java index 8fea661..736b7c5 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -10,6 +10,8 @@ import javacard.security.KeyPair; import java.io.IOException; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -21,14 +23,14 @@ public class DefaultSuite extends TestSuite { @Override public void setup(CardMngr cardManager) throws IOException { - tests.add(new Test.Simple(new Command.Support(cardManager), Result.Value.ANY)); + tests.add(new Test.Simple(new Command.Support(cardManager), ExpectedValue.ANY)); if (cfg.namedCurve != null) { String desc = "Default tests over the " + cfg.namedCurve + " curve category."; if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, desc)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, desc)); + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); } } else { if (cfg.all) { @@ -57,11 +59,11 @@ public class DefaultSuite extends TestSuite { } private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType); if (curve != null) - tests.add(new Test.Simple(curve, Result.Value.SUCCESS)); - tests.add(defaultCurveTests(cardManager, Result.Value.SUCCESS, Result.Value.SUCCESS, Result.Value.ANY, Result.Value.SUCCESS, "Default tests.")); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(new Test.Simple(curve, ExpectedValue.SUCCESS)); + tests.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default tests.")); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java index 229a5a3..f61b695 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -16,6 +16,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -51,16 +53,16 @@ public class InvalidCurvesSuite extends TestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); - tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); - tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()); - ecdhTests.add(new Test.Simple(ecdhCommand, Result.Value.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); + ecdhTests.add(new Test.Simple(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); } - tests.add(Test.Compound.all(Result.Value.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(Test.Compound.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } } diff --git a/src/cz/crcs/ectester/reader/test/Result.java b/src/cz/crcs/ectester/reader/test/Result.java index c6439ef..9110929 100644 --- a/src/cz/crcs/ectester/reader/test/Result.java +++ b/src/cz/crcs/ectester/reader/test/Result.java @@ -25,7 +25,40 @@ public class Result { return cause; } + public boolean ok() { + return value.ok(); + } + public enum Value { + SUCCESS(true), + FAILURE(false), + UXSUCCESS(false), + XFAILURE(true); + + private boolean ok; + + Value(boolean ok) { + this.ok = ok; + } + + public static Value fromExpected(ExpectedValue expected, boolean successful) { + switch (expected) { + case SUCCESS: + return successful ? SUCCESS : FAILURE; + case FAILURE: + return successful ? UXSUCCESS : XFAILURE; + case ANY: + return SUCCESS; + } + return SUCCESS; + } + + public boolean ok() { + return ok; + } + } + + public enum ExpectedValue { SUCCESS, FAILURE, ANY diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 3848df2..48280ed 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -7,6 +7,7 @@ import javax.smartcardio.CardException; import java.util.function.BiFunction; import java.util.function.Function; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; import static cz.crcs.ectester.reader.test.Result.Value; /** @@ -39,6 +40,13 @@ public abstract class Test { return result.getCause(); } + public boolean ok() { + if (!hasRun) { + return true; + } + return result.ok(); + } + public abstract String getDescription(); public boolean hasRun() { @@ -61,18 +69,14 @@ public abstract class Test { this.callback = callback; } - public Simple(Command command, Value expected, String ok, String nok) { + public Simple(Command command, ExpectedValue expected, String ok, String nok) { this(command, (cmd, resp) -> { - if (expected == Value.ANY) { - return new Result(Value.SUCCESS, ok); - } - Value respResult = resp.successful() ? Value.SUCCESS : Value.FAILURE; - boolean cond = expected == respResult; - return new Result(cond ? Value.SUCCESS : Value.FAILURE, cond ? ok : nok); + Value resultValue = Value.fromExpected(expected, resp.successful()); + return new Result(resultValue, resultValue.ok() ? ok : nok); }); } - public Simple(Command command, Value expected) { + public Simple(Command command, ExpectedValue expected) { this(command, expected, null, null); } @@ -134,10 +138,10 @@ public abstract class Test { return new Compound(callback, description, tests); } - public static Compound all(Value what, Test... all) { + public static Compound all(ExpectedValue what, Test... all) { return new Compound((tests) -> { for (Test test : tests) { - if (test.getResultValue() != what) { + if (!Value.fromExpected(what, test.ok()).ok()) { return new Result(Value.FAILURE, "At least one of the sub-tests did not have the expected result."); } } @@ -145,16 +149,16 @@ public abstract class Test { }, all); } - public static Compound all(Value what, String description, Test... all) { + public static Compound all(ExpectedValue what, String description, Test... all) { Compound result = Compound.all(what, all); result.setDescription(description); return result; } - public static Compound any(Value what, Test... any) { + public static Compound any(ExpectedValue what, Test... any) { return new Compound((tests) -> { for (Test test : tests) { - if (test.getResultValue() == what) { + if (Value.fromExpected(what, test.ok()).ok()) { return new Result(Value.SUCCESS, "At least one of the sub-tests did have the expected result."); } } @@ -162,16 +166,16 @@ public abstract class Test { }, any); } - public static Compound any(Value what, String description, Test... any) { + public static Compound any(ExpectedValue what, String description, Test... any) { Compound result = Compound.any(what, any); result.setDescription(description); return result; } - public static Compound mask(Value[] results, Test... masked) { + public static Compound mask(ExpectedValue[] results, Test... masked) { return new Compound((tests) -> { for (int i = 0; i < results.length; ++i) { - if (results[i] != Value.ANY && results[i] != tests[i].getResultValue()) { + if (!Value.fromExpected(results[i], tests[i].ok()).ok()) { return new Result(Value.FAILURE, "At least one of the sub-tests did not match the result mask."); } } @@ -179,7 +183,7 @@ public abstract class Test { }, masked); } - public static Compound mask(Value[] results, String description, Test... masked) { + public static Compound mask(ExpectedValue[] results, String description, Test... masked) { Compound result = Compound.mask(results, masked); result.setDescription(description); return result; diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index c0e8e91..cb3211d 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -15,6 +15,9 @@ import java.util.List; import java.util.Map; import java.util.function.Function; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; +import static cz.crcs.ectester.reader.test.Result.Value; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -55,23 +58,23 @@ public abstract class TestSuite { * @param description compound test description * @return test to run */ - Test defaultCurveTests(CardMngr cardManager, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressExpected, Result.Value ecdsaExpected, String description) { + Test defaultCurveTests(CardMngr cardManager, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressExpected, ExpectedValue ecdsaExpected, String description) { List tests = new LinkedList<>(); tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), Result.Value.FAILURE)); - tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), Result.Value.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); + tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), ExpectedValue.FAILURE)); tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return Test.Compound.function((testArray) -> { - Function shouldHave = (expected) -> { + Function shouldHave = (expected) -> { switch (expected) { case SUCCESS: - return "been successful"; + return "succeeded"; case FAILURE: return "failed"; case ANY: @@ -82,21 +85,21 @@ public abstract class TestSuite { for (int i = 0; i < testArray.length; ++i) { Test t = testArray[i]; - if (t.getResultValue() != Result.Value.SUCCESS) { + if (!t.ok()) { if (i == 0) { // generate - return new Result(Result.Value.FAILURE, "The generation of a key should have " + shouldHave.apply(generateExpected) + ", but it did not."); + return new Result(Value.FAILURE, "The generation of a key should have " + shouldHave.apply(generateExpected) + ", but it did not."); } else if (i == 2) { // ecdh compress - return new Result(Result.Value.FAILURE, "The ECDH should have " + shouldHave.apply(ecdhExpected) + ", but it did not."); + return new Result(Value.FAILURE, "The ECDH should have " + shouldHave.apply(ecdhExpected) + ", but it did not."); } else if (i == 1) { // ecdh normal - return new Result(Result.Value.FAILURE, "The ECDH of a compressed point should have " + shouldHave.apply(ecdhCompressExpected) + ", but it did not."); + return new Result(Value.FAILURE, "The ECDH of a compressed point should have " + shouldHave.apply(ecdhCompressExpected) + ", but it did not."); } else if (i <= 6) { // ecdh wrong, should fail - return new Result(Result.Value.FAILURE, "The ECDH of a corrupted point should have failed, but it dit not."); + return new Result(Value.FAILURE, "The ECDH of a corrupted point should have failed, but it dit not."); } else { // ecdsa - return new Result(Result.Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); + return new Result(Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); } } } - return new Result(Result.Value.SUCCESS); + return new Result(Value.SUCCESS); }, description, tests.toArray(new Test[0])); } @@ -107,12 +110,12 @@ public abstract class TestSuite { * @param setExpected expected result of the Set (curve) command * @param generateExpected expected result of the Generate command * @param ecdhExpected expected result of the ordinary ECDH command - * @param ecdhCompressedExpected + * @param ecdhCompressedExpected expected result of the ECDH command with a compressed point. * @param ecdsaExpected expected result of the ordinary ECDSA command * @param description compound test description * @return tests to run */ - List defaultCategoryTests(CardMngr cardManager, String category, byte field, Result.Value setExpected, Result.Value generateExpected, Result.Value ecdhExpected, Result.Value ecdhCompressedExpected, Result.Value ecdsaExpected, String description) { + List defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { List tests = new LinkedList<>(); Map curves = dataStore.getObjects(EC_Curve.class, category); if (curves == null) @@ -120,10 +123,10 @@ public abstract class TestSuite { for (Map.Entry entry : curves.entrySet()) { EC_Curve curve = entry.getValue(); if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), Result.Value.SUCCESS)); + tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected)); tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description)); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java index 7a2767e..ff46feb 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -16,6 +16,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; +import static cz.crcs.ectester.reader.test.Result.Value; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -55,25 +58,25 @@ public class TestVectorSuite extends TestSuite { } List testVector = new LinkedList<>(); - testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.Value.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.Value.SUCCESS)); - //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Result.Value.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Result.Value.SUCCESS)); - testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Result.Value.SUCCESS)); + testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + //tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); + testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> { Response.ECDH dh = (Response.ECDH) response; if (!dh.successful()) - return new Result(Result.Value.FAILURE, "ECDH was unsuccessful."); + return new Result(Value.FAILURE, "ECDH was unsuccessful."); if (!dh.hasSecret()) - return new Result(Result.Value.FAILURE, "ECDH response did not contain the derived secret."); + return new Result(Value.FAILURE, "ECDH response did not contain the derived secret."); if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { int firstDiff = Util.diffBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength()); - return new Result(Result.Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); + return new Result(Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); } - return new Result(Result.Value.SUCCESS); + return new Result(Value.SUCCESS); })); - tests.add(Test.Compound.all(Result.Value.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(new Test.Simple(new Command.Cleanup(cardManager), Result.Value.ANY)); + tests.add(Test.Compound.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java index 20cb405..e9389b4 100644 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java @@ -7,6 +7,8 @@ import javacard.security.KeyPair; import java.io.IOException; +import static cz.crcs.ectester.reader.test.Result.ExpectedValue; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -23,10 +25,10 @@ public class WrongCurvesSuite extends TestSuite { */ String desc = "Default tests over wrong curve params."; if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, desc)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); } if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, Result.Value.FAILURE, desc)); + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); } } } -- cgit v1.2.3-70-g09d2 From 67f1f281228245d1b4e4b3b6b750aa00ffed9970 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 5 Nov 2017 17:03:58 +0100 Subject: Fix some alignment issues. --- src/cz/crcs/ectester/reader/output/TextTestWriter.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index d697761..6fbfce7 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -25,7 +25,6 @@ public class TextTestWriter implements TestWriter { output.println("=== " + suite.getDescription()); } - private String testString(Test t, int offset) { if (!t.hasRun()) { return null; @@ -44,7 +43,6 @@ public class TextTestWriter implements TestWriter { out.append(" ┃ "); out.append(respWriter.responseSuffix(test.getResponse())); } else { - out.append(System.lineSeparator()); Test.Compound test = (Test.Compound) t; out.append(test.ok() ? "OK " : "NOK "); out.append("┳ "); -- cgit v1.2.3-70-g09d2 From 45c555818a7bf2765434f2494d56a31af7dc6cfa Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 5 Nov 2017 17:09:20 +0100 Subject: Introduce Response.error variable. - Useful to discern a response containing failing SWs created by ECTester applet, or a response created by the card when ECTester execution failed. --- src/cz/crcs/ectester/reader/output/TextTestWriter.java | 2 +- src/cz/crcs/ectester/reader/response/Response.java | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index 6fbfce7..bcebcd5 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -12,7 +12,7 @@ public class TextTestWriter implements TestWriter { private PrintStream output; private ResponseWriter respWriter; - public static int BASE_WIDTH = 72; + public static int BASE_WIDTH = 76; public TextTestWriter(PrintStream output) { this.output = output; diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 1906811..42629b4 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -7,7 +7,6 @@ import javacard.framework.ISO7816; import javacard.security.KeyPair; import javax.smartcardio.ResponseAPDU; -import java.util.List; /** * @author Jan Jancar johny@neuromancer.sk @@ -21,6 +20,7 @@ public abstract class Response { private byte[][] params; //TODO replace params with EC_Data? private boolean success = true; + private boolean error = false; public Response(ResponseAPDU response, long time) { this.resp = response; @@ -45,22 +45,28 @@ public abstract class Response { } } else { success = false; + error = true; } } - if ((short) resp.getSW() != ISO7816.SW_NO_ERROR) + if ((short) resp.getSW() != ISO7816.SW_NO_ERROR) { success = false; + error = true; + } + //try to parse numParams.. params = new byte[numParams][]; for (int i = 0; i < numParams; i++) { if (data.length - offset < 2) { success = false; + error = true; break; } short paramLength = Util.getShort(data, offset); offset += 2; if (data.length < offset + paramLength) { + error = true; success = false; break; } @@ -114,6 +120,10 @@ public abstract class Response { return this.success; } + public boolean error() { + return this.error; + } + public abstract String getDescription(); /** @@ -121,6 +131,7 @@ public abstract class Response { */ public static class AllocateKeyAgreement extends Response { byte kaType; + public AllocateKeyAgreement(ResponseAPDU response, long time, byte kaType) { super(response, time); this.kaType = kaType; @@ -134,7 +145,7 @@ public abstract class Response { } } - + public static class Allocate extends Response { private byte keyPair; -- cgit v1.2.3-70-g09d2 From aa13c1ba0082d975cb9d1f1e0f0ab1f151438b02 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 5 Nov 2017 18:52:56 +0100 Subject: Introduce Result.Value.ERROR. - Value.ERROR is used when response.error() is true. - Value.ERROR is NOK. --- src/cz/crcs/ectester/reader/Util.java | 4 +- .../ectester/reader/output/ResponseWriter.java | 2 +- src/cz/crcs/ectester/reader/response/Response.java | 4 +- src/cz/crcs/ectester/reader/test/Result.java | 44 ++++++++++++++-------- src/cz/crcs/ectester/reader/test/Test.java | 2 +- 5 files changed, 35 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index 840f4c5..4e1154b 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -287,10 +287,10 @@ public class Util { public static String getSWString(short sw) { if (sw == ISO7816.SW_NO_ERROR) { - return "OK\t(0x9000)"; + return "OK (0x9000)"; } else { String str = getSW(sw); - return String.format("fail\t(%s, 0x%04x)", str, sw); + return String.format("fail (%s, 0x%04x)", str, sw); } } diff --git a/src/cz/crcs/ectester/reader/output/ResponseWriter.java b/src/cz/crcs/ectester/reader/output/ResponseWriter.java index 0f932e7..c357233 100644 --- a/src/cz/crcs/ectester/reader/output/ResponseWriter.java +++ b/src/cz/crcs/ectester/reader/output/ResponseWriter.java @@ -31,7 +31,7 @@ public class ResponseWriter { public void outputResponse(Response r) { String out = ""; - out += String.format("%-70s", r.getDescription()) + " : "; + out += String.format("%-70s", r.getDescription()) + " ┃ "; out += responseSuffix(r); output.println(out); output.flush(); diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 42629b4..4abfd14 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -3,6 +3,7 @@ package cz.crcs.ectester.reader.response; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.reader.ec.EC_Data; import javacard.framework.ISO7816; import javacard.security.KeyPair; @@ -18,7 +19,6 @@ public abstract class Response { private short[] sws; private int numSW = 0; private byte[][] params; - //TODO replace params with EC_Data? private boolean success = true; private boolean error = false; @@ -27,7 +27,7 @@ public abstract class Response { this.time = time; } - public void parse(int numSW, int numParams) { + void parse(int numSW, int numParams) { this.numSW = numSW; this.sws = new short[numSW]; diff --git a/src/cz/crcs/ectester/reader/test/Result.java b/src/cz/crcs/ectester/reader/test/Result.java index 9110929..82f0f32 100644 --- a/src/cz/crcs/ectester/reader/test/Result.java +++ b/src/cz/crcs/ectester/reader/test/Result.java @@ -29,11 +29,29 @@ public class Result { return value.ok(); } + public boolean compareTo(Result other) { + if (other == null) { + return false; + } + return value == other.value; + } + + public boolean compareTo(Value other) { + if (other == null) { + return false; + } + return value == other; + } + + /** + * + */ public enum Value { SUCCESS(true), FAILURE(false), UXSUCCESS(false), - XFAILURE(true); + XFAILURE(true), + ERROR(false); private boolean ok; @@ -53,28 +71,24 @@ public class Result { return SUCCESS; } + public static Value fromExpected(ExpectedValue expected, boolean successful, boolean error) { + if (error) { + return ERROR; + } + return fromExpected(expected, successful); + } + public boolean ok() { return ok; } } + /** + * + */ public enum ExpectedValue { SUCCESS, FAILURE, ANY } - - public boolean compareTo(Result other) { - if (other == null) { - return false; - } - return value == other.value; - } - - public boolean compareTo(Value other) { - if (other == null) { - return false; - } - return value == other; - } } diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java index 48280ed..022ad56 100644 --- a/src/cz/crcs/ectester/reader/test/Test.java +++ b/src/cz/crcs/ectester/reader/test/Test.java @@ -71,7 +71,7 @@ public abstract class Test { public Simple(Command command, ExpectedValue expected, String ok, String nok) { this(command, (cmd, resp) -> { - Value resultValue = Value.fromExpected(expected, resp.successful()); + Value resultValue = Value.fromExpected(expected, resp.successful(), resp.error()); return new Result(resultValue, resultValue.ok() ? ok : nok); }); } -- cgit v1.2.3-70-g09d2 From ffe19211aebfd26f9c7bb404903e2a4c2da075db Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 6 Nov 2017 21:09:36 +0100 Subject: Output SWs as unsigned ints. --- src/cz/crcs/ectester/reader/output/XMLTestWriter.java | 4 ++-- .../crcs/ectester/reader/output/YAMLTestWriter.java | 6 +++--- src/cz/crcs/ectester/reader/test/TestSuite.java | 2 +- src/cz/crcs/ectester/scripts/ectester.sh | 19 +++++++++++-------- 4 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index 709d215..beb758c 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -64,13 +64,13 @@ public class XMLTestWriter implements TestWriter { responseElem.appendChild(apdu); Element naturalSW = doc.createElement("natural-sw"); - naturalSW.setTextContent(String.valueOf(r.getNaturalSW())); + naturalSW.setTextContent(String.valueOf(Short.toUnsignedInt(r.getNaturalSW()))); responseElem.appendChild(naturalSW); Element sws = doc.createElement("sws"); for (int i = 0; i < r.getNumSW(); ++i) { Element sw = doc.createElement("sw"); - sw.setTextContent(String.valueOf(r.getSW(i))); + sw.setTextContent(String.valueOf(Short.toUnsignedInt(r.getSW(i)))); sws.appendChild(sw); } responseElem.appendChild(sws); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index f0dcd3a..3b2b72d 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -50,10 +50,10 @@ public class YAMLTestWriter implements TestWriter { Map responseObj = new HashMap<>(); responseObj.put("successful", r.successful()); responseObj.put("apdu", Util.bytesToHex(r.getAPDU().getBytes())); - responseObj.put("natural_sw", r.getNaturalSW()); - List sws = new LinkedList<>(); + responseObj.put("natural_sw", Short.toUnsignedInt(r.getNaturalSW())); + List sws = new LinkedList<>(); for (int i = 0; i < r.getNumSW(); ++i) { - sws.add(r.getSW(i)); + sws.add(Short.toUnsignedInt(r.getSW(i))); } responseObj.put("sws", sws); responseObj.put("duration", r.getDuration()); diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index cb3211d..f13317c 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -93,7 +93,7 @@ public abstract class TestSuite { } else if (i == 1) { // ecdh normal return new Result(Value.FAILURE, "The ECDH of a compressed point should have " + shouldHave.apply(ecdhCompressExpected) + ", but it did not."); } else if (i <= 6) { // ecdh wrong, should fail - return new Result(Value.FAILURE, "The ECDH of a corrupted point should have failed, but it dit not."); + return new Result(Value.FAILURE, "The ECDH of a corrupted point should have failed, but it did not."); } else { // ecdsa return new Result(Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); } diff --git a/src/cz/crcs/ectester/scripts/ectester.sh b/src/cz/crcs/ectester/scripts/ectester.sh index 0de1bc3..8040096 100755 --- a/src/cz/crcs/ectester/scripts/ectester.sh +++ b/src/cz/crcs/ectester/scripts/ectester.sh @@ -20,12 +20,15 @@ esac done set -- "${positional[@]}" -if [[ $# -ne 1 ]]; then - echo "One argument expected:" >&2 - echo " ./ectester.sh [--dangerous] CARD_NAME" >&2 +if [[ $# -lt 1 ]]; then + echo "At least one argument expected:" >&2 + echo " ./ectester.sh [--dangerous] CARD_NAME [ECTester args]" >&2 exit 1 fi +card="$1" +shift + declare -a tests=("default" "test-vectors") if [[ "$dangerous" == "1" ]]; then tests+=("invalid" "wrong" "composite") @@ -34,12 +37,12 @@ fi declare -a files=() for i in $(seq 0 $((${#tests[@]} - 1))); do test="${tests[$i]}" - java -jar ECTester.jar -t ${test} -a --format yaml -l ${1}.${test} - files+=(${1}.$test) + java -jar ECTester.jar -t ${test} -a --format yaml -l ${card}.${test} $@ + files+=(${card}.$test) done if command -v tar 2>&1 >/dev/null; then - tar -czvf ${1}.tar.gz ${files[*]} + tar -czvf ${card}.tar.gz ${files[*]} elif command -v zip 2>&1 >/dev/null; then - zip ${1}.zip ${files[*]} -fi \ No newline at end of file + zip ${card}.zip ${files[*]} +fi -- cgit v1.2.3-70-g09d2