diff options
| -rw-r--r-- | !uploader/ectester.cap | bin | 13953 -> 13653 bytes | |||
| -rw-r--r-- | README.md | 73 | ||||
| -rw-r--r-- | dist/ECTester.jar | bin | 215674 -> 215702 bytes | |||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyTester.java | 36 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECTesterApplet.java | 28 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/EC_Consts.java | 9 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/data/EC_Data.java | 3 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Command.java | 12 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/ECTester.java | 93 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Response.java | 52 |
10 files changed, 169 insertions, 137 deletions
diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap Binary files differindex ff977bc..e517e19 100644 --- a/!uploader/ectester.cap +++ b/!uploader/ectester.cap @@ -1,26 +1,75 @@ -ECTester -======== +# ECTester -Tests support and behavior of smartcards with JavaCard platform with focus on Eliptic curves (TYPE_EC_FP and TYPE_EC_F2M). +Tests support and behavior of smartcards with JavaCard platform with focus on Eliptic curves (`TYPE_EC_FP` and `TYPE_EC_F2M`). -Usage ------- -1. Upload ectester.cap using your favorite tool (e.g., [GlobalPlatformPro tool](https://github.com/martinpaljak/GlobalPlatform)) -2. Run `java -jar ectester.jar` +## Usage + +1. Upload `!uploader/ectester.cap` using your favorite tool (e.g., [GlobalPlatformPro tool](https://github.com/martinpaljak/GlobalPlatform)) +2. Run `java -jar dist/ECTester.jar -t -a` 3. Inspect output log with annotated results Following operations are tested: - Allocation of new KeyPair class for specified parameters -- Generation of keypair with default curve -- Setting of custom curve and keypair generation +- Generation of KeyPair with default curve +- Setting of custom curve and KeyPair generation - Generation of shared secret via ECDH - Signature via ECDSA - Behavior of card when invalid curves/points are provided (should fail) -See `java -jar ectester.jar -h` for more. +See `java -jar ectester.jar -h` for more. + +### Options + +``` + -ln,--list-named Print the list of supported named + curves, keys and keypairs. + -dsa,--ecdsa <count> Sign data with ECDSA, [count] times. + -t,--test Test ECC support. + -dh,--ecdh <count> Do ECDH, [count] times. + -e,--export Export the defaut curve parameters of + the card(if any). + -g,--generate <amount> Generate [amount] of EC keys. + -h,--help Print help. + + -a,--all Test all curve sizes. + -b,--bit-size <bits> Set curve size. + + -c,--curve <curve_file> Use curve from file [curve_file] + (field,a,b,gx,gy,r,k). + -nc,--named-curve <cat/id> Use a named curve. + -u,--custom Use a custom curve(applet-side + embedded, SECG curves). + + -fp,--prime-field Use prime field curve. + -f2m,--binary-field Use binary field curve. + + -npub,--named-public <cat/id> Use public key from KeyDB: [cat/id] + -pub,--public <pubkey_file> Use public key from file [pubkey_file] + (wx,wy). + + -priv,--private <privkey_file> Use private key from file + [privkey_file] (s). + -npriv,--named-private <cat/id> Use private key from KeyDB: [cat/id] + + -k,--key <key_file> Use keyPair from fileĀ [key_file] + (wx,wy,s). + -nk,--named-key <cat/id> Use keyPair from KeyDB: [cat/id] + + -i,--input <input_file> Input from fileĀ [input_file], for ecdsa + signing. + -o,--output <output_file> Output into file [output_file]. + -l,--log <log_file> Log output into file [log_file]. + -v,--verbose Turn on verbose logging. + + -f,--fresh Generate fresh keys(set domain + parameters before every generation). + -s,--simulate Simulate a card with jcardsim instead + of using a terminal. + +``` + +### Example -Example output --------------- ### Test for support and with valid and invalid EC curves EC type: ALG_EC_FP diff --git a/dist/ECTester.jar b/dist/ECTester.jar Binary files differindex d82c605..21cbcf7 100644 --- a/dist/ECTester.jar +++ b/dist/ECTester.jar diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 2e3e86e..61848b8 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -68,19 +68,6 @@ public class ECKeyTester { return length; } - private short testKA_validPoint(KeyAgreement ka, ECPrivateKey privateKey, byte[] pubkeyBuffer, short pubkeyOffset, short pubkeyLength, byte[] outputBuffer, short outputOffset) { - return testKA(ka, privateKey, pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); - } - - private short testKA_invalidPoint(KeyAgreement ka, ECPrivateKey privateKey, byte[] pubkeyBuffer, short pubkeyOffset, short pubkeyLength, byte[] outputBuffer, short outputOffset) { - pubkeyBuffer[(short) (pubkeyLength - 2)] += 0xcc; - pubkeyBuffer[(short) (pubkeyLength - 3)] += 0xcc; - short result = testKA(ka, privateKey, pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); - pubkeyBuffer[(short) (pubkeyLength - 2)] -= 0xcc; - pubkeyBuffer[(short) (pubkeyLength - 3)] -= 0xcc; - return result; - } - /** * Tests ECDH secret generation with given {@code privateKey} and {@code publicKey}. * Uses {@code pubkeyBuffer} at {@code pubkeyOffset} for computations. @@ -92,19 +79,15 @@ public class ECKeyTester { * @param pubkeyOffset * @param outputBuffer * @param outputOffset + * @param corruption * @return derived secret length **/ - public short testECDH_validPoint(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset) { + public short testECDH(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { short length = publicKey.getW(pubkeyBuffer, pubkeyOffset); - return testKA_validPoint(ecdhKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); + EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, length); + return testKA(ecdhKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); } - public short testECDH_invalidPoint(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset) { - short length = publicKey.getW(pubkeyBuffer, pubkeyOffset); - return testKA_invalidPoint(ecdhKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); - } - - /** * Tests ECDHC secret generation with given {@code privateKey} and {@code publicKey}. * Uses {@code pubkeyBuffer} at {@code pubkeyOffset} for computations. @@ -116,17 +99,14 @@ public class ECKeyTester { * @param pubkeyOffset * @param outputBuffer * @param outputOffset + * @param corruption * @return ISO7816.SW_NO_ERROR on correct operation, * exception reason otherwise */ - public short testECDHC_validPoint(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset) { - short length = publicKey.getW(pubkeyBuffer, pubkeyOffset); - return testKA_validPoint(ecdhcKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); - } - - public short testECDHC_invalidPoint(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset) { + public short testECDHC(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { short length = publicKey.getW(pubkeyBuffer, pubkeyOffset); - return testKA_invalidPoint(ecdhcKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); + EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, length); + return testKA(ecdhcKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); } /** diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 6623647..cdb0fbd 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -324,7 +324,7 @@ public class ECTesterApplet extends Applet { * @param apdu P1 = byte pubkey (KEYPAIR_*) * P2 = byte privkey (KEYPAIR_*) * DATA = byte export (EXPORT_TRUE || EXPORT_FALSE) - * byte invalid (00 = valid, !00 = invalid) + * byte corruption (00 = valid, !00 = invalid) */ private void insECDH(APDU apdu) { apdu.setIncomingAndReceive(); @@ -333,9 +333,9 @@ public class ECTesterApplet extends Applet { byte pubkey = apdubuf[ISO7816.OFFSET_P1]; byte privkey = apdubuf[ISO7816.OFFSET_P2]; byte export = apdubuf[ISO7816.OFFSET_CDATA]; - byte invalid = apdubuf[(short) (ISO7816.OFFSET_CDATA + 1)]; + byte corruption = apdubuf[(short) (ISO7816.OFFSET_CDATA + 1)]; - short len = ecdh(pubkey, privkey, export, invalid, apdubuf, (short) 0); + short len = ecdh(pubkey, privkey, export, corruption, apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); } @@ -436,7 +436,6 @@ public class ECTesterApplet extends Applet { } /** - * * @param keyPair KeyPair to corrupt * @param key key to corrupt (EC_Consts.KEY_* | ...) * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) @@ -494,26 +493,21 @@ public class ECTesterApplet extends Applet { } /** - * @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 invalid whether to invalidate the pubkey before ECDH - * @param buffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)} - * @param offset output offset in buffer + * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param export whether to export ECDH secret + * @param corruption whether to invalidate the pubkey before ECDH + * @param buffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)} + * @param offset output offset in buffer * @return length of data written to the buffer */ - private short ecdh(byte pubkey, byte privkey, byte export, byte invalid, byte[] buffer, short offset) { + private short ecdh(byte pubkey, byte privkey, byte export, byte corruption, byte[] buffer, short offset) { short length = 0; KeyPair pub = ((pubkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; - short secretLength; - if (invalid != 0) { - secretLength = keyTester.testECDH_invalidPoint((ECPrivateKey) priv.getPrivate(), (ECPublicKey) pub.getPublic(), ramArray, (short) 0, ramArray2, (short) 0); - } else { - secretLength = keyTester.testECDH_validPoint((ECPrivateKey) priv.getPrivate(), (ECPublicKey) pub.getPublic(), ramArray, (short) 0, ramArray2, (short) 0); - } + short secretLength = keyTester.testECDH((ECPrivateKey) priv.getPrivate(), (ECPublicKey) pub.getPublic(), ramArray, (short) 0, ramArray2, (short) 0, corruption); Util.setShort(buffer, offset, keyTester.getSW()); length += 2; diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 68fb4c9..50f14a9 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -1224,15 +1224,6 @@ public class EC_Consts { return length; } - public static short getCorruptCurveParameter(byte curve, short param, byte[] outputBuffer, short outputOffset, byte corruptionType) { - short length = getCurveParameter(curve, param, outputBuffer, outputOffset); - if (length <= 0) { - return length; - } - corruptParameter(corruptionType, outputBuffer, outputOffset, length); - return length; - } - public static void corruptParameter(byte corruption, byte[] buffer, short offset, short length) { switch (corruption) { case CORRUPTION_NONE: diff --git a/src/cz/crcs/ectester/data/EC_Data.java b/src/cz/crcs/ectester/data/EC_Data.java index 0c4bda2..98b2d59 100644 --- a/src/cz/crcs/ectester/data/EC_Data.java +++ b/src/cz/crcs/ectester/data/EC_Data.java @@ -139,7 +139,7 @@ public class EC_Data { } } - InputStream keysStream = this.getClass().getResourceAsStream("/cz/crcs/ectester/data" + dir + "/keys.xml"); + InputStream keysStream = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/keys.xml"); if (keysStream != null) { Document keysDoc = db.parse(keysStream); keysDoc.normalize(); @@ -149,7 +149,6 @@ public class EC_Data { Node direct = directs.item(i); if (direct instanceof Element) { Element elem = (Element) direct; - String tag = elem.getTagName(); NodeList childs = elem.getChildNodes(); String id = null; diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java index cb2321a..876e999 100644 --- a/src/cz/crcs/ectester/reader/Command.java +++ b/src/cz/crcs/ectester/reader/Command.java @@ -250,7 +250,7 @@ public abstract class Command { private byte pubkey; private byte privkey; private byte export; - private byte invalid; + private byte corruption; /** * Creates the INS_ECDH instruction. @@ -259,16 +259,16 @@ public abstract class Command { * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret - * @param invalid whether to invalidate the pubkey before ECDH + * @param corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* || ...) */ - public ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, byte invalid) { + public ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, byte corruption) { super(cardManager); this.pubkey = pubkey; this.privkey = privkey; this.export = export; - this.invalid = invalid; + this.corruption = corruption; - byte[] data = new byte[]{export, invalid}; + byte[] data = new byte[]{export, corruption}; this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); } @@ -278,7 +278,7 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDH(response, elapsed, pubkey, privkey, export, invalid); + return new Response.ECDH(response, elapsed, pubkey, privkey, export, corruption); } } diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 68343e2..cc8e0aa 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -62,15 +62,20 @@ public class ECTester { private String optCurveFile = null; private boolean optCustomCurve = false; + private boolean optAnyPublic = false; private String optNamedPublic = null; private String optPublic = null; + private boolean optAnyPrivate = false; private String optNamedPrivate = null; private String optPrivate = null; + private boolean optAnyKey = false; private String optNamedKey = null; private String optKey = null; + private boolean optAnyKeypart = false; + private String optLog = null; private boolean optVerbose = false; @@ -107,10 +112,7 @@ public class ECTester { dataDB = new EC_Data(); //if list, print and quit if (cli.hasOption("list-named")) { - Map<String, EC_Category> categories = dataDB.getCategories(); - for (EC_Category cat : categories.values()) { - System.out.println("\t- " + cat.getName() + ": " + (cat.getDesc() == null ? "" : cat.getDesc())); - } + list(); return; } @@ -193,7 +195,7 @@ public class ECTester { * -t / --test * -dh / --ecdh * -dsa / --ecdsa [data_file] - * --list-named + * -ln / --list-named * * Options: * -b / --bit-size [b] // -a / --all @@ -224,7 +226,7 @@ public class ECTester { OptionGroup actions = new OptionGroup(); actions.setRequired(true); actions.addOption(Option.builder("h").longOpt("help").desc("Print help.").build()); - actions.addOption(Option.builder().longOpt("list-named").desc("Print the list of supported named curves and keys.").build()); + actions.addOption(Option.builder("ln").longOpt("list-named").desc("Print the list of supported named curves and keys.").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.").build()); @@ -238,7 +240,7 @@ public class ECTester { opts.addOptionGroup(size); OptionGroup curve = new OptionGroup(); - curve.addOption(Option.builder("n").longOpt("named").desc("Use a named curve.").hasArg().argName("cat/id").build()); + curve.addOption(Option.builder("nc").longOpt("named-curve").desc("Use a named curve.").hasArg().argName("cat/id").build()); curve.addOption(Option.builder("c").longOpt("curve").desc("Use curve from file [curve_file] (field,a,b,gx,gy,r,k).").hasArg().argName("curve_file").build()); curve.addOption(Option.builder("u").longOpt("custom").desc("Use a custom curve(applet-side embedded, SECG curves).").build()); opts.addOptionGroup(curve); @@ -291,12 +293,17 @@ public class ECTester { optNamedPublic = cli.getOptionValue("named-public"); optPublic = cli.getOptionValue("public"); + optAnyPublic = (optPublic != null) || (optNamedPublic != null); optNamedPrivate = cli.getOptionValue("named-private"); optPrivate = cli.getOptionValue("private"); + optAnyPrivate = (optPrivate != null) || (optNamedPrivate != null); optNamedKey = cli.getOptionValue("named-key"); optKey = cli.getOptionValue("key"); + optAnyKey = (optKey != null) || (optNamedKey != null); + optAnyKeypart = optAnyKey || optAnyPublic || optAnyPrivate; + if (cli.hasOption("log")) { optLog = cli.getOptionValue("log", String.format("ECTESTER_log_%d.log", System.currentTimeMillis() / 1000)); } @@ -330,7 +337,7 @@ public class ECTester { System.err.print("Need to specify field with -fp or -f2m. (not both)"); return false; } - if (optKey != null || optPublic != null || optPrivate != null || optNamedKey != null || optNamedPublic != null || optNamedPrivate != null) { + if (optAnyKeypart) { System.err.println("Keys should not be specified when exporting curve params."); return false; } @@ -352,7 +359,7 @@ public class ECTester { System.err.print("Need to specify field with -fp or -f2m. (not both)"); return false; } - if (optKey != null || optPublic != null || optPrivate != null || optNamedKey != null || optNamedPublic != null || optNamedPrivate != null) { + if (optAnyKeypart) { System.err.println("Keys should not be specified when generating keys."); return false; } @@ -402,11 +409,8 @@ public class ECTester { return false; } - boolean hasPublic = (optPublic != null) || (optNamedPublic != null); - boolean hasPrivate = (optPrivate != null) || (optNamedPrivate != null); - boolean hasKey = (optKey != null) || (optNamedKey != null); - if ((hasPublic) != (hasPrivate) && !hasKey) { - System.err.println("You have cannot only specify a part of a keypair."); + if ((optAnyPublic) != (optAnyPrivate) && !optAnyKey) { + System.err.println("You cannot only specify a part of a keypair."); return false; } @@ -421,6 +425,43 @@ public class ECTester { } /** + * List categories and named curves. + */ + private void list() { + Map<String, EC_Category> categories = dataDB.getCategories(); + for (EC_Category cat : categories.values()) { + System.out.println("\t- " + cat.getName() + ": " + (cat.getDesc() == null ? "" : cat.getDesc())); + + Map<String, EC_Curve> curves = cat.getObjects(EC_Curve.class); + int size = curves.size(); + if (size > 0) { + System.out.print("\t\tCurves: "); + for (Map.Entry<String, EC_Curve> curve : curves.entrySet()) { + System.out.print(curve.getKey()); + size--; + if (size > 0) + System.out.print(", "); + } + System.out.println(); + } + + Map<String, EC_Key> keys = cat.getObjects(EC_Key.class); + size = keys.size(); + if (size > 0) { + System.out.print("\t\tKeys: "); + for (Map.Entry<String, EC_Key> key : keys.entrySet()) { + System.out.print(key.getKey()); + size--; + if (size > 0) + System.out.print(", "); + } + System.out.println(); + } + System.out.println(); + } + } + + /** * Prints help. */ private void help() { @@ -595,12 +636,14 @@ public class ECTester { systemOutLogger.println(Response.toString(prepare)); List<Command> generate = new LinkedList<>(); - if (optPublic != null || optPrivate != null || optKey != null) { + if (optAnyPublic || optAnyPrivate || optAnyKey) { generate.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL)); generate.add(prepareKey(ECTesterApplet.KEYPAIR_REMOTE)); } else { generate.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH)); } + byte pubkey = (optAnyPublic || optAnyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; + byte privkey = (optAnyPrivate || optAnyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; FileWriter out = null; if (optOutput != null) { @@ -613,13 +656,13 @@ public class ECTester { while (done < optECDHCount) { List<Response> ecdh = Command.sendAll(generate); - Response.ECDH perform = new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_TRUE, (byte) 0).send(); + Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, (byte) 0).send(); ecdh.add(perform); systemOutLogger.println(Response.toString(ecdh)); if (!perform.successful() || !perform.hasSecret()) { if (retry < 10) { - retry++; + ++retry; continue; } else { System.err.println("Couldn't obtain ECDH secret from card response."); @@ -657,7 +700,7 @@ public class ECTester { } Command generate; - if (optKey != null || (optPublic != null && optPrivate != null)) { + if (optAnyKeypart) { generate = prepareKey(ECTesterApplet.KEYPAIR_LOCAL); } else { generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL); @@ -688,7 +731,7 @@ public class ECTester { if (!perform.successful() || !perform.hasSignature()) { if (retry < 10) { - retry++; + ++retry; continue; } else { System.err.println("Couldn't obtain ECDSA signature from card response."); @@ -751,7 +794,11 @@ public class ECTester { commands.add(new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, domainParams, external)); } else { // Set default curve - commands.add(new Command.Clear(cardManager, keyPair)); + /* 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 commands; @@ -833,8 +880,10 @@ public class ECTester { private List<Command> testCurve() throws IOException { List<Command> commands = new LinkedList<>(); commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH)); - commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, (byte) 0)); - commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, (byte) 1)); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE)); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM)); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE)); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO)); commands.add(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null)); return commands; } diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index 25b5817..21e80d7 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -129,7 +129,7 @@ public abstract class Response { } else { suffix = String.format("%s %s", Util.getPrintError(r.getSW1()), Util.getPrintError(r.getSW2())); } - out.append(String.format("%-55s:%5d ms : %s", message, r.time / 1000000, suffix)); + out.append(String.format("%-58s:%4d ms : %s", message, r.time / 1000000, suffix)); if (i < responses.size() - 1) { out.append("\n"); } @@ -294,42 +294,6 @@ public abstract class Response { parse(generated, 0); } - /* - private int getIndex(byte key) { - for (int i = 0; i < contents.length; i++) { - if (key == contents[i]) - return i; - } - return -1; - } - - public boolean hasPublic(byte keyPair) { - if ((export & ECTesterApplet.EXPORT_PUBLIC) == 0 || (export & keyPair) == 0) - return false; - int index = getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PUBLIC)); - return index != -1 && hasParam(index); - } - - public boolean hasPrivate(byte keyPair) { - if ((export & ECTesterApplet.EXPORT_PRIVATE) == 0 || (export & keyPair) == 0) - return false; - int index = getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PRIVATE)); - return index != -1 && hasParam(index); - } - - public byte[] getPublic(byte keyPair) { - //calculate index and getParam - int index = getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PUBLIC)); - return getParam(index); - } - - public byte[] getPrivate(byte keyPair) { - //calculate index and getParam - int index = getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PRIVATE)); - return getParam(index); - } - */ - @Override public String toString() { String key; @@ -458,14 +422,14 @@ public abstract class Response { private byte pubkey; private byte privkey; private byte export; - private byte invalid; + private byte corruption; - protected ECDH(ResponseAPDU response, long time, byte pubkey, byte privkey, byte export, byte invalid) { + protected ECDH(ResponseAPDU response, long time, byte pubkey, byte privkey, byte export, byte corruption) { super(response, time); this.pubkey = pubkey; this.privkey = privkey; this.export = export; - this.invalid = invalid; + this.corruption = corruption; parse(1, (export == ECTesterApplet.EXPORT_TRUE) ? 1 : 0); } @@ -482,7 +446,13 @@ public abstract class Response { public String toString() { String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; - String validity = invalid != 0 ? "invalid" : "valid"; + String validity; + + if (corruption == EC_Consts.CORRUPTION_NONE) { + validity = "valid"; + } else { + validity = Util.getCorruption(corruption); + } return String.format("ECDH of %s pubkey and %s privkey(%s point)", pub, priv, validity); } } |
