aboutsummaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/reader/ECTester.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cz/crcs/ectester/reader/ECTester.java')
-rw-r--r--src/cz/crcs/ectester/reader/ECTester.java185
1 files changed, 46 insertions, 139 deletions
diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java
index 1f70d4f..e5a2b70 100644
--- a/src/cz/crcs/ectester/reader/ECTester.java
+++ b/src/cz/crcs/ectester/reader/ECTester.java
@@ -27,15 +27,12 @@ import javacard.security.KeyPair;
import org.apache.commons.cli.*;
import javax.smartcardio.CardException;
-import javax.smartcardio.CommandAPDU;
-import javax.smartcardio.ResponseAPDU;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.List;
/**
@@ -187,10 +184,8 @@ public class ECTester {
}
} catch (MissingArgumentException maex) {
System.err.println("Option, " + maex.getOption().getOpt() + " requires an argument: " + maex.getOption().getArgName());
- } catch (AlreadySelectedException asex) {
- System.err.println(asex.getMessage());
} catch (ParseException | CardException pex) {
- pex.printStackTrace();
+ System.err.println(pex.getMessage());
} catch (NumberFormatException nfex) {
System.err.println("Not a number. " + nfex.getMessage());
nfex.printStackTrace(System.err);
@@ -370,8 +365,7 @@ public class ECTester {
*/
private void generate() throws CardException, IOException {
byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
- CommandAPDU[] prepare = prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass);
- cardManager.send(prepare);
+ List<Response> prepare = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass));
FileWriter keysFile = new FileWriter(optOutput);
keysFile.write("index;time;pubW;privS\n");
@@ -379,30 +373,27 @@ public class ECTester {
int generated = 0;
int retry = 0;
while (generated < optGenerateAmount || optGenerateAmount == 0) {
- CommandAPDU generate = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, (byte) (ECTesterApplet.EXPORT_BOTH | ECTesterApplet.KEYPAIR_LOCAL));
- long elapsed = -System.nanoTime();
- ResponseAPDU response = cardManager.send(generate);
- elapsed += System.nanoTime();
+ Command.Generate generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (byte) (ECTesterApplet.EXPORT_BOTH | ECTesterApplet.KEYPAIR_LOCAL));
+ Response.Generate response = generate.send();
+ long elapsed = response.getDuration();
- byte[] bytes = response.getData();
- if (bytes.length <= 2) {
- //error, retry 10 times
+ if (!response.successful()) {
if (retry < 10) {
retry++;
+ continue;
} else {
System.err.println("Keys could not be generated.");
break;
}
- } else {
- short publicLength = Util.getShort(bytes, 2);
- String pubkey = Util.bytesToHex(bytes, 4, publicLength, false);
- short privateLength = Util.getShort(bytes, 4 + publicLength);
- String privkey = Util.bytesToHex(bytes, 6 + publicLength, privateLength, false);
-
- keysFile.write(String.format("%d;%d;%s;%s\n", generated, elapsed / 1000000, pubkey, privkey));
- keysFile.flush();
- generated++;
}
+ systemOutLogger.println(response.toString());
+
+ String pub = Util.bytesToHex(response.getPublic(ECTesterApplet.KEYPAIR_LOCAL), false);
+ String priv = Util.bytesToHex(response.getPrivate(ECTesterApplet.KEYPAIR_LOCAL), false);
+ String line = String.format("%d;%d;%s;%s\n", generated, elapsed / 1000000, pub, priv);
+ keysFile.write(line);
+ keysFile.flush();
+ generated++;
}
keysFile.close();
}
@@ -460,23 +451,24 @@ public class ECTester {
*/
private void ecdh() throws IOException, CardException {
byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
- CommandAPDU[] curve = prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass);
- cardManager.send(curve);
+ List<Response> ecdh = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass));
if (optPublic != null || optPrivate != null || optKey != null) {
- CommandAPDU local = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE);
- cardManager.send(local);
- CommandAPDU remote = prepareKey(ECTesterApplet.KEYPAIR_REMOTE);
- cardManager.send(remote);
+ Response local = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE).send();
+ Response remote = prepareKey(ECTesterApplet.KEYPAIR_REMOTE).send();
+ ecdh.add(local);
+ ecdh.add(remote);
} else {
- CommandAPDU both = insGenerate(ECTesterApplet.KEYPAIR_BOTH, ECTesterApplet.EXPORT_NONE);
- cardManager.send(both);
+ Response both = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH, ECTesterApplet.EXPORT_NONE).send();
+ ecdh.add(both);
}
- CommandAPDU ecdh = insECDH(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_ECDH, (byte) 0);
- ResponseAPDU response = cardManager.send(ecdh);
- //TODO print response SWs/error codes
- //TODO output to file
+ Response.ECDH perform = new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_ECDH, (byte) 0).send();
+ ecdh.add(perform);
+ for (Response r : ecdh) {
+ systemOutLogger.println(r.toString());
+ }
+ //TODO check perform.hasSecret(), write perform.getSecret to file if -o
}
/**
@@ -487,16 +479,15 @@ public class ECTester {
*/
private void ecdsa() throws CardException, IOException {
byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
- CommandAPDU[] curve = prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass);
- cardManager.send(curve);
+ List<Response> ecdsa = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass));
+ Response keys;
if (optKey != null || (optPublic != null && optPrivate != null)) {
- CommandAPDU set = prepareKey(ECTesterApplet.KEYPAIR_LOCAL);
- cardManager.send(set);
+ keys = prepareKey(ECTesterApplet.KEYPAIR_LOCAL).send();
} else {
- CommandAPDU generate = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE);
- cardManager.send(generate);
+ keys = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE).send();
}
+ ecdsa.add(keys);
//read file, if asked to sign
byte[] data = null;
@@ -509,96 +500,12 @@ public class ECTester {
data = Files.readAllBytes(in.toPath());
}
- CommandAPDU ecdsa = insECDSA(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_SIG, data);
- ResponseAPDU response = cardManager.send(ecdsa);
- //TODO print response SWs/error codes
- //TODO output to file
- }
-
- /**
- * Creates the INS_ALLOCATE instruction.
- *
- * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...)
- * @param keyLength key length to set
- * @param keyClass key class to allocate
- * @return apdu to send
- */
- private CommandAPDU insAllocate(byte keyPair, short keyLength, byte keyClass) {
- byte[] data = new byte[]{0, 0, keyClass};
- Util.setShort(data, 0, keyLength);
-
- return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data);
- }
-
- /**
- * Creates the INS_SET instruction.
- *
- * @param keyPair which keyPair to set params on, local/remote (KEYPAIR_* || ...)
- * @param export whether to export set params from keyPair
- * @param curve curve to set (EC_Consts.CURVE_*)
- * @param params parameters to set (EC_Consts.PARAMETER_* | ...)
- * @param corrupted parameters to corrupt (EC_Consts.PARAMETER_* | ...)
- * @param corruption corruption type (EC_Consts.CORRUPTION_*)
- * @param external external curve data, can be null
- * @return apdu to send
- */
- private CommandAPDU insSet(byte keyPair, byte export, byte curve, short params, short corrupted, byte corruption, byte[] external) {
- int len = external != null ? 6 + 2 + external.length : 6;
- byte[] data = new byte[len];
- data[0] = curve;
- Util.setShort(data, 1, params);
- Util.setShort(data, 3, corrupted);
- data[5] = corruption;
- if (external != null) {
- System.arraycopy(external, 0, data, 6, external.length);
- }
-
- return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET, keyPair, export, data);
- }
-
- /**
- * Creates the INS_GENERATE instruction.
- *
- * @param keyPair which keyPair to generate, local/remote (KEYPAIR_* || ...)
- * @param export whether to export generated keys from keyPair
- * @return apdu to send
- */
- private CommandAPDU insGenerate(byte keyPair, byte export) {
- return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_GENERATE, keyPair, export);
- }
-
- /**
- * Creates the INS_ECDH instruction.
- *
- * @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
- * @return apdu to send
- */
- private CommandAPDU insECDH(byte pubkey, byte privkey, byte export, byte invalid) {
- byte[] data = new byte[]{export, invalid};
-
- return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data);
- }
-
- /**
- * Creates the INS_ECDSA instruction.
- *
- * @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.
- * @return apdu to send
- */
- private CommandAPDU insECDSA(byte keyPair, byte export, byte[] 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);
+ Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_SIG, data).send();
+ ecdsa.add(perform);
+ for (Response r : ecdsa) {
+ systemOutLogger.println(r.toString());
}
-
- return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keyPair, export, data);
+ //TODO output to file
}
/**
@@ -608,23 +515,23 @@ public class ECTester {
* @return an array of CommandAPDUs to send in order to prepare the keypair/s.
* @throws IOException if curve file cannot be found/opened
*/
- private CommandAPDU[] prepareCurve(byte keyPair, short keyLength, byte keyClass) throws IOException {
- List<CommandAPDU> commands = new ArrayList<>();
- commands.add(insAllocate(keyPair, keyLength, keyClass));
+ private List<Command> prepareCurve(byte keyPair, short keyLength, byte keyClass) throws IOException {
+ List<Command> commands = new ArrayList<>();
+ commands.add(new Command.Allocate(cardManager, keyPair, keyLength, keyClass));
short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M;
if (optNamed) {
- commands.add(insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.getCurve(keyLength, keyClass), domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, null));
+ commands.add(new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.getCurve(keyLength, keyClass), domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, null));
}
if (optCurve != null) {
byte[] external = ParamReader.flatten(domainParams, ParamReader.readFile(optCurve));
if (external == null) {
throw new IOException("Couldn't read the curve file correctly.");
}
- commands.add(insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external));
+ commands.add(new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external));
}
- return commands.toArray(new CommandAPDU[commands.size()]);
+ return commands;
}
/**
@@ -632,7 +539,7 @@ public class ECTester {
* @return a CommandAPDU setting params loaded on the keyPair/s
* @throws IOException if any of the key files cannot be found/opened
*/
- private CommandAPDU prepareKey(byte keyPair) throws IOException {
+ private Command prepareKey(byte keyPair) throws IOException {
short params = EC_Consts.PARAMETERS_NONE;
byte[] data = null;
if (optKey != null) {
@@ -656,7 +563,7 @@ public class ECTester {
*/
throw new IOException("Couldn't read the key file correctly.");
}
- return insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data);
+ return new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data);
}
public static void main(String[] args) {