diff options
| author | petrs | 2017-06-16 17:24:48 +0200 |
|---|---|---|
| committer | petrs | 2017-06-16 17:24:48 +0200 |
| commit | 7ab02af142427a996cedf7540ffa3345612fe1bc (patch) | |
| tree | 058f525742c9af67506bee5a4108c06369c1f3ea | |
| parent | 359b4bb5be1a822e389e54b9697504f4f0b43d34 (diff) | |
| download | ECTester-7ab02af142427a996cedf7540ffa3345612fe1bc.tar.gz ECTester-7ab02af142427a996cedf7540ffa3345612fe1bc.tar.zst ECTester-7ab02af142427a996cedf7540ffa3345612fe1bc.zip | |
| -rw-r--r-- | !uploader/ectester.cap | bin | 15878 -> 16008 bytes | |||
| -rw-r--r-- | dist/ECTester.jar | bin | 721271 -> 726928 bytes | |||
| -rw-r--r-- | dist/README.TXT | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyTester.java | 15 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECTesterApplet.java | 66 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Command.java | 27 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/ECTester.java | 7 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Response.java | 17 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Util.java | 33 |
9 files changed, 156 insertions, 11 deletions
diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap Binary files differindex 689610b..3b9e650 100644 --- a/!uploader/ectester.cap +++ b/!uploader/ectester.cap diff --git a/dist/ECTester.jar b/dist/ECTester.jar Binary files differindex f44b150..8195c6f 100644 --- a/dist/ECTester.jar +++ b/dist/ECTester.jar diff --git a/dist/README.TXT b/dist/README.TXT index fe19a92..5d6fa17 100644 --- a/dist/README.TXT +++ b/dist/README.TXT @@ -11,7 +11,7 @@ JAR files manifest file (MANIFEST.MF). To run the project from the command line, go to the dist folder and type the following: -java -jar "SimpleAPDU.jar" +java -jar "ECTester.jar" To distribute this project, zip up the dist folder (including the lib folder) and distribute the ZIP file. diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index b18073f..0b3c1e0 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -3,6 +3,7 @@ package cz.crcs.ectester.applet; import javacard.framework.CardRuntimeException; import javacard.framework.ISO7816; +import javacard.framework.ISOException; import javacard.security.*; /** @@ -19,20 +20,20 @@ public class ECKeyTester { private short sw = ISO7816.SW_NO_ERROR; - public short allocateECDH() { + public short allocateECDH(byte algorithm) { sw = ISO7816.SW_NO_ERROR; try { - ecdhKeyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH, false); + ecdhKeyAgreement = KeyAgreement.getInstance(algorithm, false); } catch (CardRuntimeException ce) { sw = ce.getReason(); } return sw; } - public short allocateECDHC() { + public short allocateECDHC(byte algorithm) { sw = ISO7816.SW_NO_ERROR; try { - ecdhcKeyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DHC, false); + ecdhcKeyAgreement = KeyAgreement.getInstance(algorithm, false); } catch (CardRuntimeException ce) { sw = ce.getReason(); } @@ -55,9 +56,11 @@ public class ECKeyTester { sw = AppletUtil.kaCheck(ka); sw = AppletUtil.keypairCheck(privatePair); sw = AppletUtil.keypairCheck(publicPair); - - ka.init(privatePair.getPrivate()); short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); + // reached ok + ka.init(privatePair.getPrivate()); // throws UNITIALIZED KEY when ALG_EC_SVDP_DHC_PLAIN is used + //ISOException.throwIt((short) 0x666); + pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength); length = ka.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); } catch (CardRuntimeException ce) { diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index c2e2c63..447d9af 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -28,6 +28,7 @@ package cz.crcs.ectester.applet; import javacard.framework.*; import javacard.security.ECPrivateKey; import javacard.security.ECPublicKey; +import javacard.security.KeyAgreement; import javacard.security.KeyPair; import javacard.security.RandomData; import javacardx.apdu.ExtendedLength; @@ -69,7 +70,21 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final short SW_KEYPAIR_NULL = (short) 0x0ee3; public static final short SW_KA_NULL = (short) 0x0ee4; public static final short SW_SIGNATURE_NULL = (short) 0x0ee5; - public static final short SW_OBJECT_NULL = (short) 0x0ee6; + public static final short SW_OBJECT_NULL = (short) 0x0ee6; + public static final short SW_KA_UNSUPPORTED = (short) 0x0ee7; + + + // Class javacard.security.KeyAgreement + // javacard.security.KeyAgreement Fields: + public static final byte KeyAgreement_ALG_EC_SVDP_DH = 1; + public static final byte KeyAgreement_ALG_EC_SVDP_DH_KDF = 1; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC = 2; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC_KDF = 2; + public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN = 3; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC_PLAIN = 4; + public static final byte KeyAgreement_ALG_EC_PACE_GM = 5; + public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6; + public static final byte KeyAgreement_ALG_DH_PLAIN = 7; private static final short ARRAY_LENGTH = (short) 0xff; @@ -116,8 +131,10 @@ public class ECTesterApplet extends Applet implements ExtendedLength { keyGenerator = new ECKeyGenerator(); keyTester = new ECKeyTester(); - ecdhSW = keyTester.allocateECDH(); - ecdhcSW = keyTester.allocateECDHC(); + ecdhSW = keyTester.allocateECDH(KeyAgreement.ALG_EC_SVDP_DH); + ecdhcSW = keyTester.allocateECDHC(KeyAgreement.ALG_EC_SVDP_DHC); + //ecdhSW = keyTester.allocateECDH((byte) 3); + //ecdhcSW = keyTester.allocateECDHC((byte) 4); ecdsaSW = keyTester.allocateECDSA(); } register(); @@ -144,6 +161,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength { short length = 0; switch (ins) { + case INS_ALLOCATE_KA: + length = insAllocateKA(apdu); + break; case INS_ALLOCATE: length = insAllocate(apdu); break; @@ -186,7 +206,45 @@ public class ECTesterApplet extends Applet implements ExtendedLength { apdu.setOutgoingAndSend((short) 0, length); } else ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); } - + + /** + * Allocates KeyAgreement object. returns allocate SW + * + * @param apdu DATA = byte KeyAgreementType + * @return length of response + */ + private short insAllocateKA(APDU apdu) { + short cdata = apdu.getOffsetCdata(); + byte kaType = apduArray[cdata]; +/* + short sw = SW_KA_UNSUPPORTED; + switch (kaType) { + case KeyAgreement_ALG_EC_SVDP_DH: // no break + case KeyAgreement_ALG_EC_SVDP_DH_PLAIN: + case KeyAgreement_ALG_EC_PACE_GM: + case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: + sw = keyTester.allocateECDH(kaType); + break; + case KeyAgreement_ALG_EC_SVDP_DHC: + case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: + sw = keyTester.allocateECDHC(kaType); + break; + default: + sw = SW_KA_UNSUPPORTED; + break; + } +*/ + // Allocate given type into both DH and DHC objects + short sw = keyTester.allocateECDH(kaType); + short offset = 0; + Util.setShort(apdu.getBuffer(), offset, sw); + offset += 2; + + //sw = keyTester.allocateECDHC(kaType); + Util.setShort(apdu.getBuffer(), offset, sw); + offset += 2; + return offset; + } /** * Allocates local and remote keyPairs. * returns allocate SWs diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java index 5b7be01..8cb3a30 100644 --- a/src/cz/crcs/ectester/reader/Command.java +++ b/src/cz/crcs/ectester/reader/Command.java @@ -211,6 +211,33 @@ public abstract class Command { 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); + } + } /** * diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 3b5b84f..bb555f9 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -22,6 +22,7 @@ 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.ec.EC_Category; @@ -219,6 +220,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 +261,8 @@ public class ECTester { opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); opts.addOption(Option.builder("y").longOpt("yes").desc("Accept all warnings and prompts.").build()); + opts.addOption(Option.builder("ka").longOpt("ka-type").desc("Set KeyAgreement object [type], corresponds to JC.KeyAgreement constants.").hasArg().argName("type").optionalArg(true).build()); + CommandLineParser parser = new DefaultParser(); return parser.parse(opts, args); } @@ -442,6 +446,7 @@ public class ECTester { private void ecdh() throws IOException, CardException { byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; List<Response> prepare = new LinkedList<>(); + prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.kaType).send()); // Prepare KeyAgreement or required type prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass).send()); Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass); if (curve != null) @@ -581,6 +586,7 @@ public class ECTester { public boolean all; public boolean primeField = false; public boolean binaryField = false; + public byte kaType = KeyAgreement_ALG_EC_SVDP_DH; public String namedCurve; public String curveFile; @@ -628,6 +634,7 @@ public class ECTester { all = cli.hasOption("all"); primeField = cli.hasOption("fp"); binaryField = cli.hasOption("f2m"); + kaType = Byte.parseByte(cli.getOptionValue("ka-type", "1")); namedCurve = cli.getOptionValue("named-curve"); customCurve = cli.hasOption("custom"); diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index d74724c..3df956e 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -154,9 +154,26 @@ public abstract class Response { 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; diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index e7b7338..754cda3 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -1,6 +1,12 @@ package cz.crcs.ectester.reader; import cz.crcs.ectester.applet.ECTesterApplet; +import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_PACE_GM; +import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; +import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC; +import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN; +import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN; +import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY; import cz.crcs.ectester.applet.EC_Consts; import javacard.framework.ISO7816; import javacard.security.CryptoException; @@ -339,4 +345,31 @@ public class Util { } return algo; } + + public static String getKATypeString(byte kaType) { + String kaTypeString = "unknown"; + switch (kaType) { + case KeyAgreement_ALG_EC_SVDP_DH: + kaTypeString = "ALG_EC_SVDP_DH"; + break; + case KeyAgreement_ALG_EC_SVDP_DH_PLAIN: + kaTypeString = "ALG_EC_SVDP_DH_PLAIN"; + break; + case KeyAgreement_ALG_EC_PACE_GM: + kaTypeString = "ALG_EC_PACE_GM"; + break; + case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: + kaTypeString = "ALG_EC_SVDP_DH_PLAIN_XY"; + break; + case KeyAgreement_ALG_EC_SVDP_DHC: + kaTypeString = "ALG_EC_SVDP_DHC"; + break; + case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: + kaTypeString = "ALG_EC_SVDP_DHC_PLAIN"; + break; + default: + kaTypeString = "unknown"; + } + return kaTypeString; + } } |
