summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_Curve.java54
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_Data.java31
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_KAResult.java4
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_Params.java24
-rw-r--r--src/cz/crcs/ectester/common/util/ByteUtil.java122
-rw-r--r--src/cz/crcs/ectester/common/util/CardUtil.java (renamed from src/cz/crcs/ectester/common/Util.java)124
-rw-r--r--src/cz/crcs/ectester/reader/CardMngr.java16
-rw-r--r--src/cz/crcs/ectester/reader/ECTesterReader.java10
-rw-r--r--src/cz/crcs/ectester/reader/command/Command.java18
-rw-r--r--src/cz/crcs/ectester/reader/output/ResponseWriter.java6
-rw-r--r--src/cz/crcs/ectester/reader/output/XMLTestWriter.java6
-rw-r--r--src/cz/crcs/ectester/reader/output/YAMLTestWriter.java6
-rw-r--r--src/cz/crcs/ectester/reader/response/Response.java15
-rw-r--r--src/cz/crcs/ectester/reader/test/TestVectorSuite.java6
-rw-r--r--src/cz/crcs/ectester/standalone/ECTesterStandalone.java21
-rw-r--r--src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java10
16 files changed, 275 insertions, 198 deletions
diff --git a/src/cz/crcs/ectester/common/ec/EC_Curve.java b/src/cz/crcs/ectester/common/ec/EC_Curve.java
index 478ce7d..19228dc 100644
--- a/src/cz/crcs/ectester/common/ec/EC_Curve.java
+++ b/src/cz/crcs/ectester/common/ec/EC_Curve.java
@@ -1,7 +1,7 @@
package cz.crcs.ectester.common.ec;
import cz.crcs.ectester.applet.EC_Consts;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import javacard.security.KeyPair;
import java.math.BigInteger;
@@ -60,10 +60,10 @@ public class EC_Curve extends EC_Params {
field = new ECFieldFp(new BigInteger(1, getData(0)));
} else {
byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M);
- int m = Util.getShort(fieldData[0], 0);
- int e1 = Util.getShort(fieldData[1], 0);
- int e2 = Util.getShort(fieldData[2], 0);
- int e3 = Util.getShort(fieldData[3], 0);
+ int m = ByteUtil.getShort(fieldData[0], 0);
+ int e1 = ByteUtil.getShort(fieldData[1], 0);
+ int e2 = ByteUtil.getShort(fieldData[2], 0);
+ int e3 = ByteUtil.getShort(fieldData[3], 0);
int[] powers = new int[]{e1, e2, e3};
field = new ECFieldF2m(m, powers);
}
@@ -80,8 +80,50 @@ public class EC_Curve extends EC_Params {
BigInteger n = new BigInteger(1, getParam(EC_Consts.PARAMETER_R)[0]);
- int h = Util.getShort(getParam(EC_Consts.PARAMETER_K)[0], 0);
+ int h = ByteUtil.getShort(getParam(EC_Consts.PARAMETER_K)[0], 0);
return new ECParameterSpec(curve, generator, n, h);
}
+
+ public static EC_Curve fromSpec(ECParameterSpec spec) {
+ EllipticCurve curve = spec.getCurve();
+ ECField field = curve.getField();
+
+ short bits = (short) field.getFieldSize();
+ byte[][] params;
+ int paramIndex = 0;
+ byte fieldType;
+ if (field instanceof ECFieldFp) {
+ ECFieldFp primeField = (ECFieldFp) field;
+ params = new byte[5][];
+ params[paramIndex++] = primeField.getP().toByteArray();
+ fieldType = KeyPair.ALG_EC_FP;
+ } else if (field instanceof ECFieldF2m) {
+ ECFieldF2m binaryField = (ECFieldF2m) field;
+ params = new byte[8][];
+ params[paramIndex] = new byte[2];
+ ByteUtil.setShort(params[paramIndex++], 0, (short) binaryField.getM());
+ int[] powers = binaryField.getMidTermsOfReductionPolynomial();
+ for (int i = 0; i < 3; ++i) {
+ params[paramIndex] = new byte[2];
+ ByteUtil.setShort(params[paramIndex++], 0, (short) powers[i]);
+ }
+ fieldType = KeyPair.ALG_EC_F2M;
+ } else {
+ throw new IllegalArgumentException("ECParameterSpec with an unknnown field.");
+ }
+
+ ECPoint generator = spec.getGenerator();
+
+ params[paramIndex++] = generator.getAffineX().toByteArray();
+ params[paramIndex++] = generator.getAffineY().toByteArray();
+
+ params[paramIndex++] = spec.getOrder().toByteArray();
+ params[paramIndex] = new byte[2];
+ ByteUtil.setShort(params[paramIndex], 0, (short) spec.getCofactor());
+
+ EC_Curve result = new EC_Curve(bits, fieldType);
+ result.readByteArray(params);
+ return result;
+ }
}
diff --git a/src/cz/crcs/ectester/common/ec/EC_Data.java b/src/cz/crcs/ectester/common/ec/EC_Data.java
index acd282a..c048ef7 100644
--- a/src/cz/crcs/ectester/common/ec/EC_Data.java
+++ b/src/cz/crcs/ectester/common/ec/EC_Data.java
@@ -1,6 +1,6 @@
package cz.crcs.ectester.common.ec;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import java.io.*;
import java.util.*;
@@ -8,9 +8,10 @@ import java.util.regex.Pattern;
/**
* A list of byte arrays for holding EC data.
- *
+ * <p>
* The data can be read from a byte array via <code>readBytes()</code>, from a CSV via <code>readCSV()</code>.
* The data can be exported to a byte array via <code>flatten()</code> or to a string array via <code>expand()</code>.
+ *
* @author Jan Jancar johny@neuromancer.sk
*/
public abstract class EC_Data {
@@ -67,7 +68,7 @@ public abstract class EC_Data {
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (byte[] param : data) {
byte[] length = new byte[2];
- Util.setShort(length, 0, (short) param.length);
+ ByteUtil.setShort(length, 0, (short) param.length);
out.write(length, 0, 2);
out.write(param, 0, param.length);
@@ -79,7 +80,7 @@ public abstract class EC_Data {
public String[] expand() {
List<String> out = new ArrayList<>(count);
for (byte[] param : data) {
- out.add(Util.bytesToHex(param, false));
+ out.add(ByteUtil.bytesToHex(param, false));
}
return out.toArray(new String[out.size()]);
@@ -97,9 +98,9 @@ public abstract class EC_Data {
private static byte[] parse(String param) {
byte[] data;
if (param.startsWith("0x") || param.startsWith("0X")) {
- data = Util.hexToBytes(param.substring(2));
+ data = ByteUtil.hexToBytes(param.substring(2));
} else {
- data = Util.hexToBytes(param);
+ data = ByteUtil.hexToBytes(param);
}
if (data == null)
return new byte[0];
@@ -141,12 +142,16 @@ public abstract class EC_Data {
}
public boolean readBytes(byte[] bytes) {
+ if (bytes == null) {
+ return false;
+ }
+
int offset = 0;
for (int i = 0; i < count; i++) {
if (bytes.length - offset < 2) {
return false;
}
- short paramLength = Util.getShort(bytes, offset);
+ short paramLength = ByteUtil.getShort(bytes, offset);
offset += 2;
if (bytes.length < offset + paramLength) {
return false;
@@ -158,6 +163,18 @@ public abstract class EC_Data {
return true;
}
+ public boolean readByteArray(byte[][] bytes) {
+ if (bytes == null || count != bytes.length) {
+ return false;
+ }
+
+ for (int i = 0; i < count; ++i) {
+ data[i] = new byte[bytes[i].length];
+ System.arraycopy(bytes[i], 0, data[i], 0, bytes[i].length);
+ }
+ return true;
+ }
+
public void writeCSV(OutputStream out) throws IOException {
Writer w = new OutputStreamWriter(out);
w.write(String.join(",", expand()));
diff --git a/src/cz/crcs/ectester/common/ec/EC_KAResult.java b/src/cz/crcs/ectester/common/ec/EC_KAResult.java
index 3b74c57..a7b3cd5 100644
--- a/src/cz/crcs/ectester/common/ec/EC_KAResult.java
+++ b/src/cz/crcs/ectester/common/ec/EC_KAResult.java
@@ -1,6 +1,6 @@
package cz.crcs.ectester.common.ec;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.CardUtil;
/**
* A result of EC based Key agreement operation.
@@ -56,7 +56,7 @@ public class EC_KAResult extends EC_Data {
@Override
public String toString() {
- String algo = Util.getKA(ka);
+ String algo = CardUtil.getKA(ka);
return "<" + getId() + "> " + algo + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc);
}
diff --git a/src/cz/crcs/ectester/common/ec/EC_Params.java b/src/cz/crcs/ectester/common/ec/EC_Params.java
index 3fada93..1c066e7 100644
--- a/src/cz/crcs/ectester/common/ec/EC_Params.java
+++ b/src/cz/crcs/ectester/common/ec/EC_Params.java
@@ -1,7 +1,7 @@
package cz.crcs.ectester.common.ec;
import cz.crcs.ectester.applet.EC_Consts;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
@@ -125,12 +125,12 @@ public class EC_Params extends EC_Data {
byte[] param = data[i];
if (masked == EC_Consts.PARAMETER_F2M) {
//add m, e_1, e_2, e_3
- param = Util.concatenate(param, data[i + 1]);
- if (!Util.allValue(data[i + 2], (byte) 0)) {
- param = Util.concatenate(param, data[i + 2]);
+ param = ByteUtil.concatenate(param, data[i + 1]);
+ if (!ByteUtil.allValue(data[i + 2], (byte) 0)) {
+ param = ByteUtil.concatenate(param, data[i + 2]);
}
- if (!Util.allValue(data[i + 3], (byte) 0)) {
- param = Util.concatenate(param, data[i + 3]);
+ if (!ByteUtil.allValue(data[i + 3], (byte) 0)) {
+ param = ByteUtil.concatenate(param, data[i + 3]);
}
if (!(param.length == 4 || param.length == 8))
throw new RuntimeException("PARAMETER_F2M length is not 8.(should be)");
@@ -138,14 +138,14 @@ public class EC_Params extends EC_Data {
if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) {
//read another param (the y coord) and put into X962 format.
byte[] y = data[i + 1];
- param = Util.concatenate(new byte[]{4}, param, y); //<- ugly but works!
+ param = ByteUtil.concatenate(new byte[]{4}, param, y); //<- ugly but works!
}
if (param.length == 0)
throw new RuntimeException("Empty parameter read?");
//write length
byte[] length = new byte[2];
- Util.setShort(length, 0, (short) param.length);
+ ByteUtil.setShort(length, 0, (short) param.length);
out.write(length, 0, 2);
//write data
out.write(param, 0, param.length);
@@ -175,15 +175,15 @@ public class EC_Params extends EC_Data {
byte[] param = data[index];
if (masked == EC_Consts.PARAMETER_F2M) {
for (int i = 0; i < 4; ++i) {
- out.add(Util.bytesToHex(data[index + i], false));
+ out.add(ByteUtil.bytesToHex(data[index + i], false));
}
index += 4;
} else if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) {
- out.add(Util.bytesToHex(param, false));
- out.add(Util.bytesToHex(data[index + 1], false));
+ out.add(ByteUtil.bytesToHex(param, false));
+ out.add(ByteUtil.bytesToHex(data[index + 1], false));
index += 2;
} else {
- out.add(Util.bytesToHex(param, false));
+ out.add(ByteUtil.bytesToHex(param, false));
index++;
}
}
diff --git a/src/cz/crcs/ectester/common/util/ByteUtil.java b/src/cz/crcs/ectester/common/util/ByteUtil.java
new file mode 100644
index 0000000..939e487
--- /dev/null
+++ b/src/cz/crcs/ectester/common/util/ByteUtil.java
@@ -0,0 +1,122 @@
+package cz.crcs.ectester.common.util;
+
+/**
+ * Utility class, some byte/hex manipulation, convenient byte[] methods.
+ *
+ * @author Petr Svenda petr@svenda.com
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class ByteUtil {
+ public static short getShort(byte[] array, int offset) {
+ return (short) (((array[offset] & 0xFF) << 8) | (array[offset + 1] & 0xFF));
+ }
+
+ public static void setShort(byte[] array, int offset, short value) {
+ array[offset + 1] = (byte) (value & 0xFF);
+ array[offset] = (byte) ((value >> 8) & 0xFF);
+ }
+
+ 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 i;
+ }
+ }
+ 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) {
+ for (byte a : array) {
+ if (a != value)
+ return false;
+ }
+ return true;
+ }
+
+ public static byte[] hexToBytes(String hex) {
+ return hexToBytes(hex, true);
+ }
+
+ public static byte[] hexToBytes(String hex, boolean bigEndian) {
+ hex = hex.replace(" ", "");
+ int len = hex.length();
+ StringBuilder sb = new StringBuilder();
+
+ if (len % 2 == 1) {
+ sb.append("0");
+ ++len;
+ }
+
+ if (bigEndian) {
+ sb.append(hex);
+ } else {
+ for (int i = 0; i < len / 2; ++i) {
+ if (sb.length() >= 2) {
+ sb.insert(sb.length() - 2, hex.substring(2 * i, 2 * i + 2));
+ } else {
+ sb.append(hex.substring(2 * i, 2 * i + 2));
+ }
+
+ }
+ }
+
+ String data = sb.toString();
+ byte[] result = new byte[len / 2];
+ for (int i = 0; i < len; i += 2) {
+ result[i / 2] = (byte) ((Character.digit(data.charAt(i), 16) << 4)
+ + (Character.digit(data.charAt(i + 1), 16)));
+ }
+ return result;
+ }
+
+ public static String byteToHex(byte data) {
+ return String.format("%02x", data);
+ }
+
+ public static String bytesToHex(byte[] data) {
+ return bytesToHex(data, true);
+ }
+
+ public static String bytesToHex(byte[] data, boolean addSpace) {
+ return bytesToHex(data, 0, data.length, addSpace);
+ }
+
+ public static String bytesToHex(byte[] data, int offset, int len) {
+ return bytesToHex(data, offset, len, true);
+ }
+
+ public static String bytesToHex(byte[] data, int offset, int len, boolean addSpace) {
+ StringBuilder buf = new StringBuilder();
+ for (int i = offset; i < (offset + len); i++) {
+ buf.append(byteToHex(data[i]));
+ if (addSpace && i != (offset + len - 1)) {
+ buf.append(" ");
+ }
+ }
+ return (buf.toString());
+ }
+
+ public static byte[] concatenate(byte[]... arrays) {
+ int len = 0;
+ for (byte[] array : arrays) {
+ if (array == null)
+ continue;
+ len += array.length;
+ }
+ byte[] out = new byte[len];
+ int offset = 0;
+ for (byte[] array : arrays) {
+ if (array == null || array.length == 0)
+ continue;
+ System.arraycopy(array, 0, out, offset, array.length);
+ offset += array.length;
+ }
+ return out;
+ }
+}
diff --git a/src/cz/crcs/ectester/common/Util.java b/src/cz/crcs/ectester/common/util/CardUtil.java
index 0136493..a94c773 100644
--- a/src/cz/crcs/ectester/common/Util.java
+++ b/src/cz/crcs/ectester/common/util/CardUtil.java
@@ -1,4 +1,4 @@
-package cz.crcs.ectester.common;
+package cz.crcs.ectester.common.util;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
@@ -7,127 +7,7 @@ import javacard.security.CryptoException;
import static cz.crcs.ectester.applet.ECTesterApplet.*;
-/**
- * Utility class, some byte/hex manipulation, convenient byte[] methods.
- *
- * @author Petr Svenda petr@svenda.com
- * @author Jan Jancar johny@neuromancer.sk
- */
-public class Util {
-
- public static short getShort(byte[] array, int offset) {
- return (short) (((array[offset] & 0xFF) << 8) | (array[offset + 1] & 0xFF));
- }
-
- public static void setShort(byte[] array, int offset, short value) {
- array[offset + 1] = (byte) (value & 0xFF);
- array[offset] = (byte) ((value >> 8) & 0xFF);
- }
-
- 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 i;
- }
- }
- 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) {
- for (byte a : array) {
- if (a != value)
- return false;
- }
- return true;
- }
-
- public static byte[] hexToBytes(String hex) {
- return hexToBytes(hex, true);
- }
-
- public static byte[] hexToBytes(String hex, boolean bigEndian) {
- hex = hex.replace(" ", "");
- int len = hex.length();
- StringBuilder sb = new StringBuilder();
-
- if (len % 2 == 1) {
- sb.append("0");
- ++len;
- }
-
- if (bigEndian) {
- sb.append(hex);
- } else {
- for (int i = 0; i < len / 2; ++i) {
- if (sb.length() >= 2) {
- sb.insert(sb.length() - 2, hex.substring(2 * i, 2 * i + 2));
- } else {
- sb.append(hex.substring(2 * i, 2 * i + 2));
- }
-
- }
- }
-
- String data = sb.toString();
- byte[] result = new byte[len / 2];
- for (int i = 0; i < len; i += 2) {
- result[i / 2] = (byte) ((Character.digit(data.charAt(i), 16) << 4)
- + (Character.digit(data.charAt(i + 1), 16)));
- }
- return result;
- }
-
- public static String byteToHex(byte data) {
- return String.format("%02x", data);
- }
-
- public static String bytesToHex(byte[] data) {
- return bytesToHex(data, true);
- }
-
- public static String bytesToHex(byte[] data, boolean addSpace) {
- return bytesToHex(data, 0, data.length, addSpace);
- }
-
- public static String bytesToHex(byte[] data, int offset, int len) {
- return bytesToHex(data, offset, len, true);
- }
-
- public static String bytesToHex(byte[] data, int offset, int len, boolean addSpace) {
- StringBuilder buf = new StringBuilder();
- for (int i = offset; i < (offset + len); i++) {
- buf.append(byteToHex(data[i]));
- if (addSpace && i != (offset + len - 1)) {
- buf.append(" ");
- }
- }
- return (buf.toString());
- }
-
- public static byte[] concatenate(byte[]... arrays) {
- int len = 0;
- for (byte[] array : arrays) {
- if (array == null)
- continue;
- len += array.length;
- }
- byte[] out = new byte[len];
- int offset = 0;
- for (byte[] array : arrays) {
- if (array == null || array.length == 0)
- continue;
- System.arraycopy(array, 0, out, offset, array.length);
- offset += array.length;
- }
- return out;
- }
-
+public class CardUtil {
public static String getSWSource(short sw) {
switch (sw) {
case ISO7816.SW_NO_ERROR:
diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java
index ad5b368..cea46bc 100644
--- a/src/cz/crcs/ectester/reader/CardMngr.java
+++ b/src/cz/crcs/ectester/reader/CardMngr.java
@@ -2,7 +2,7 @@ package cz.crcs.ectester.reader;
import com.licel.jcardsim.io.CAD;
import com.licel.jcardsim.io.JavaxSmartCardInterface;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import javacard.framework.AID;
import javax.smartcardio.*;
@@ -80,7 +80,7 @@ public class CardMngr {
//reset the card
if (verbose)
- System.out.println(Util.bytesToHex(card.getATR().getBytes()));
+ System.out.println(ByteUtil.bytesToHex(card.getATR().getBytes()));
cardFound = true;
}
@@ -109,7 +109,7 @@ public class CardMngr {
try {
card = terminal.connect("*");
ATR atr = card.getATR();
- System.out.println(terminalIndex + " : " + terminal.getName() + " - " + Util.bytesToHex(atr.getBytes()));
+ System.out.println(terminalIndex + " : " + terminal.getName() + " - " + ByteUtil.bytesToHex(atr.getBytes()));
terminalIndex++;
} catch (CardException ex) {
ex.printStackTrace(System.out);
@@ -227,7 +227,7 @@ public class CardMngr {
System.out.println(">>>>");
System.out.println(apdu);
- System.out.println(Util.bytesToHex(apdu.getBytes()));
+ System.out.println(ByteUtil.bytesToHex(apdu.getBytes()));
}
long elapsed = -System.nanoTime();
@@ -238,7 +238,7 @@ public class CardMngr {
if (verbose) {
System.out.println(responseAPDU);
- System.out.println(Util.bytesToHex(responseAPDU.getBytes()));
+ System.out.println(ByteUtil.bytesToHex(responseAPDU.getBytes()));
}
if (responseAPDU.getSW1() == (byte) 0x61) {
@@ -248,7 +248,7 @@ public class CardMngr {
responseAPDU = channel.transmit(apduToSend);
if (verbose)
- System.out.println(Util.bytesToHex(responseAPDU.getBytes()));
+ System.out.println(ByteUtil.bytesToHex(responseAPDU.getBytes()));
}
if (verbose) {
@@ -277,7 +277,7 @@ public class CardMngr {
if (verbose) {
System.out.println(">>>>");
System.out.println(apdu);
- System.out.println(Util.bytesToHex(apdu.getBytes()));
+ System.out.println(ByteUtil.bytesToHex(apdu.getBytes()));
}
ResponseAPDU response = simulator.transmitCommand(apdu);
@@ -285,7 +285,7 @@ public class CardMngr {
if (verbose) {
System.out.println(response);
- System.out.println(Util.bytesToHex(responseBytes));
+ System.out.println(ByteUtil.bytesToHex(responseBytes));
System.out.println("<<<<");
}
diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java
index 2c57107..d32d9d8 100644
--- a/src/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/src/cz/crcs/ectester/reader/ECTesterReader.java
@@ -24,10 +24,10 @@ package cz.crcs.ectester.reader;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.common.cli.CLITools;
-import cz.crcs.ectester.common.Util;
import cz.crcs.ectester.common.ec.EC_Params;
import cz.crcs.ectester.common.output.OutputLogger;
import cz.crcs.ectester.common.test.TestException;
+import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.output.*;
@@ -385,8 +385,8 @@ public class ECTesterReader {
}
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);
+ String pub = ByteUtil.bytesToHex(export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_W), false);
+ String priv = ByteUtil.bytesToHex(export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S), false);
String line = String.format("%d;%d;%s;%s\n", generated, elapsed / 1000000, pub, priv);
keysFile.write(line);
keysFile.flush();
@@ -507,7 +507,7 @@ public class ECTesterReader {
}
if (out != null) {
- out.write(String.format("%d;%d;%s\n", done, perform.getDuration() / 1000000, Util.bytesToHex(perform.getSecret(), false)));
+ out.write(String.format("%d;%d;%s\n", done, perform.getDuration() / 1000000, ByteUtil.bytesToHex(perform.getSecret(), false)));
}
++done;
@@ -584,7 +584,7 @@ public class ECTesterReader {
}
if (out != null) {
- out.write(String.format("%d;%d;%s\n", done, perform.getDuration() / 1000000, Util.bytesToHex(perform.getSignature(), false)));
+ out.write(String.format("%d;%d;%s\n", done, perform.getDuration() / 1000000, ByteUtil.bytesToHex(perform.getSignature(), false)));
}
++done;
diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java
index 9d23322..b60db53 100644
--- a/src/cz/crcs/ectester/reader/command/Command.java
+++ b/src/cz/crcs/ectester/reader/command/Command.java
@@ -2,11 +2,11 @@ package cz.crcs.ectester.reader.command;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
+import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
import cz.crcs.ectester.reader.response.Response;
-import cz.crcs.ectester.common.Util;
import cz.crcs.ectester.common.ec.EC_Curve;
import cz.crcs.ectester.common.ec.EC_Key;
import cz.crcs.ectester.common.ec.EC_Keypair;
@@ -174,7 +174,7 @@ public abstract class Command {
if (privkey == null) {
throw new IOException("Couldn't read the private key file correctly.");
}
- data = Util.concatenate(data, privkey);
+ data = ByteUtil.concatenate(data, privkey);
}
return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, params, data);
}
@@ -203,7 +203,7 @@ public abstract class Command {
this.keyClass = keyClass;
byte[] data = new byte[]{0, 0, keyClass};
- Util.setShort(data, 0, keyLength);
+ ByteUtil.setShort(data, 0, keyLength);
this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data);
}
@@ -296,7 +296,7 @@ public abstract class Command {
int len = external != null ? 2 + external.length : 2;
byte[] data = new byte[len];
- Util.setShort(data, 0, params);
+ ByteUtil.setShort(data, 0, params);
if (external != null) {
System.arraycopy(external, 0, data, 2, external.length);
}
@@ -337,7 +337,7 @@ public abstract class Command {
this.corruption = corruption;
byte[] data = new byte[3];
- Util.setShort(data, 0, params);
+ ByteUtil.setShort(data, 0, params);
data[2] = corruption;
this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CORRUPT, keyPair, key, data);
@@ -403,7 +403,7 @@ public abstract class Command {
this.params = params;
byte[] data = new byte[2];
- Util.setShort(data, 0, params);
+ ByteUtil.setShort(data, 0, params);
this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_EXPORT, keyPair, key, data);
}
@@ -446,7 +446,7 @@ public abstract class Command {
this.type = type;
byte[] data = new byte[]{export, 0,0, type};
- Util.setShort(data, 1, corruption);
+ ByteUtil.setShort(data, 1, corruption);
this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data);
}
@@ -489,7 +489,7 @@ public abstract class Command {
this.pubkey = pubkey;
byte[] data = new byte[3 + pubkey.length];
- Util.setShort(data, 0, corruption);
+ ByteUtil.setShort(data, 0, corruption);
data[2] = type;
System.arraycopy(pubkey, 0, data, 3, pubkey.length);
@@ -526,7 +526,7 @@ public abstract class Command {
int len = raw != null ? raw.length : 0;
byte[] data = new byte[2 + len];
- Util.setShort(data, 0, (short) len);
+ ByteUtil.setShort(data, 0, (short) len);
if (raw != null) {
System.arraycopy(raw, 0, data, 2, len);
}
diff --git a/src/cz/crcs/ectester/reader/output/ResponseWriter.java b/src/cz/crcs/ectester/reader/output/ResponseWriter.java
index 0f5b6e8..1dbfdfa 100644
--- a/src/cz/crcs/ectester/reader/output/ResponseWriter.java
+++ b/src/cz/crcs/ectester/reader/output/ResponseWriter.java
@@ -1,6 +1,6 @@
package cz.crcs.ectester.reader.output;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.CardUtil;
import cz.crcs.ectester.reader.response.Response;
import java.io.PrintStream;
@@ -20,11 +20,11 @@ public class ResponseWriter {
for (int j = 0; j < r.getNumSW(); ++j) {
short sw = r.getSW(j);
if (sw != 0) {
- suffix.append(" ").append(Util.getSWString(sw));
+ suffix.append(" ").append(CardUtil.getSWString(sw));
}
}
if (suffix.length() == 0) {
- suffix.append(" [").append(Util.getSW(r.getNaturalSW())).append("]");
+ suffix.append(" [").append(CardUtil.getSW(r.getNaturalSW())).append("]");
}
return String.format("%4d ms ┃ %s", r.getDuration() / 1000000, suffix);
}
diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
index 0a5155b..ebc93ac 100644
--- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
@@ -1,7 +1,7 @@
package cz.crcs.ectester.reader.output;
import cz.crcs.ectester.common.test.CompoundTest;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.response.Response;
import cz.crcs.ectester.common.test.Test;
@@ -51,7 +51,7 @@ public class XMLTestWriter implements TestWriter {
Element commandElem = doc.createElement("command");
Element apdu = doc.createElement("apdu");
- apdu.setTextContent(Util.bytesToHex(c.getAPDU().getBytes()));
+ apdu.setTextContent(ByteUtil.bytesToHex(c.getAPDU().getBytes()));
commandElem.appendChild(apdu);
return commandElem;
@@ -62,7 +62,7 @@ public class XMLTestWriter implements TestWriter {
responseElem.setAttribute("successful", r.successful() ? "true" : "false");
Element apdu = doc.createElement("apdu");
- apdu.setTextContent(Util.bytesToHex(r.getAPDU().getBytes()));
+ apdu.setTextContent(ByteUtil.bytesToHex(r.getAPDU().getBytes()));
responseElem.appendChild(apdu);
Element naturalSW = doc.createElement("natural-sw");
diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
index 84f1eac..d8350ac 100644
--- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
@@ -1,7 +1,7 @@
package cz.crcs.ectester.reader.output;
import cz.crcs.ectester.common.test.CompoundTest;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.response.Response;
import cz.crcs.ectester.common.test.Test;
@@ -44,14 +44,14 @@ public class YAMLTestWriter implements TestWriter {
private Map<String, Object> commandObject(Command c) {
Map<String, Object> commandObj = new HashMap<>();
- commandObj.put("apdu", Util.bytesToHex(c.getAPDU().getBytes()));
+ commandObj.put("apdu", ByteUtil.bytesToHex(c.getAPDU().getBytes()));
return commandObj;
}
private Map<String, Object> responseObject(Response r) {
Map<String, Object> responseObj = new HashMap<>();
responseObj.put("successful", r.successful());
- responseObj.put("apdu", Util.bytesToHex(r.getAPDU().getBytes()));
+ responseObj.put("apdu", ByteUtil.bytesToHex(r.getAPDU().getBytes()));
responseObj.put("natural_sw", Short.toUnsignedInt(r.getNaturalSW()));
List<Integer> sws = new LinkedList<>();
for (int i = 0; i < r.getNumSW(); ++i) {
diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java
index 4158ac3..d8edf9e 100644
--- a/src/cz/crcs/ectester/reader/response/Response.java
+++ b/src/cz/crcs/ectester/reader/response/Response.java
@@ -2,7 +2,8 @@ package cz.crcs.ectester.reader.response;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
+import cz.crcs.ectester.common.util.CardUtil;
import javacard.framework.ISO7816;
import javacard.security.KeyPair;
@@ -36,7 +37,7 @@ public abstract class Response {
//parse SWs in response
for (int i = 0; i < numSW; ++i) {
if (getLength() >= (offset + 2)) {
- short sw = Util.getShort(data, offset);
+ short sw = ByteUtil.getShort(data, offset);
offset += 2;
sws[i] = sw;
if (sw != ISO7816.SW_NO_ERROR) {
@@ -62,7 +63,7 @@ public abstract class Response {
error = true;
break;
}
- short paramLength = Util.getShort(data, offset);
+ short paramLength = ByteUtil.getShort(data, offset);
offset += 2;
if (data.length < offset + paramLength) {
error = true;
@@ -140,7 +141,7 @@ public abstract class Response {
@Override
public String getDescription() {
- return String.format("Allocated KeyAgreement(%s) object", Util.getKATypeString(this.kaType));
+ return String.format("Allocated KeyAgreement(%s) object", CardUtil.getKATypeString(this.kaType));
}
}
@@ -289,7 +290,7 @@ public abstract class Response {
@Override
public String getDescription() {
- String corrupt = Util.getCorruption(corruption);
+ String corrupt = CardUtil.getCorruption(corruption);
String pair;
if (keyPair == ECTesterApplet.KEYPAIR_BOTH) {
@@ -476,7 +477,7 @@ public abstract class Response {
@Override
public String getDescription() {
- String algo = Util.getKA(type);
+ String algo = CardUtil.getKA(type);
String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote";
String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote";
@@ -485,7 +486,7 @@ public abstract class Response {
if (corruption == EC_Consts.CORRUPTION_NONE) {
validity = "unchanged";
} else {
- validity = Util.getCorruption(corruption);
+ validity = CardUtil.getCorruption(corruption);
}
return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity);
}
diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java
index 77653d1..98172f3 100644
--- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java
@@ -5,10 +5,10 @@ import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.common.test.CompoundTest;
import cz.crcs.ectester.common.test.Result;
import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
-import cz.crcs.ectester.common.Util;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.common.ec.*;
import cz.crcs.ectester.reader.response.Response;
@@ -72,8 +72,8 @@ public class TestVectorSuite extends TestSuite {
return new Result(Value.FAILURE, "ECDH was unsuccessful.");
if (!dh.hasSecret())
return new Result(Value.FAILURE, "ECDH response did not contain the derived secret.");
- if (!Util.compareBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength())) {
- int firstDiff = Util.diffBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength());
+ if (!ByteUtil.compareBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength())) {
+ int firstDiff = ByteUtil.diffBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength());
return new Result(Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + ".");
}
return new Result(Value.SUCCESS);
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 049626e..9f100d0 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -2,6 +2,7 @@ package cz.crcs.ectester.standalone;
import cz.crcs.ectester.common.cli.*;
import cz.crcs.ectester.common.ec.EC_Curve;
+import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent;
@@ -21,6 +22,7 @@ import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
import java.security.spec.ECParameterSpec;
import java.util.*;
import java.util.stream.Collectors;
@@ -49,12 +51,12 @@ public class ECTesterStandalone {
try {
cli = parseArgs(args);
- if (cli.hasOption("help") || cli.getNext() == null) {
- CLITools.help("ECTesterStandalone.jar", CLI_HEADER, opts, optParser, CLI_FOOTER, true);
- return;
- } else if (cli.hasOption("version")) {
+ if (cli.hasOption("version")) {
CLITools.version(DESCRIPTION, LICENSE);
return;
+ } else if (cli.hasOption("help") || cli.getNext() == null) {
+ CLITools.help("ECTesterStandalone.jar", CLI_HEADER, opts, optParser, CLI_FOOTER, true);
+ return;
}
@@ -209,12 +211,19 @@ public class ECTesterStandalone {
}
kpg.initialize(curve.toSpec());
}
+ System.out.println("index;time;pubW;privS");
int amount = Integer.parseInt(cli.getOptionValue("generate.amount", "1"));
for (int i = 0; i < amount; ++i) {
+ long elapsed = -System.nanoTime();
KeyPair kp = kpg.genKeyPair();
+ elapsed += System.nanoTime();
+ ECPublicKey publicKey = (ECPublicKey) kp.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate();
- System.out.println(privateKey);
+
+ String pub = ByteUtil.bytesToHex(publicKey.getEncoded(), false);
+ String priv = ByteUtil.bytesToHex(privateKey.getEncoded(), false);
+ System.out.println(String.format("%d;%d;%s;%s", i, elapsed / 1000000, pub, priv));
}
}
}
@@ -253,6 +262,8 @@ public class ECTesterStandalone {
ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate();
ECParameterSpec params = privateKey.getParams();
System.out.println(params);
+ EC_Curve curve = EC_Curve.fromSpec(params);
+ System.out.println(curve);
}
}
}
diff --git a/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java b/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java
index 8ad425b..381ce70 100644
--- a/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java
+++ b/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java
@@ -12,12 +12,16 @@ public class KeyGenerationTestable implements Testable {
private KeyPair kp;
private KeyPairGenerator kpg;
- private int keysize;
- private ECParameterSpec spec;
+ private int keysize = 0;
+ private ECParameterSpec spec = null;
private boolean hasRun;
private boolean error = false;
private boolean ok;
+ public KeyGenerationTestable(KeyPairGenerator kpg) {
+ this.kpg = kpg;
+ }
+
public KeyGenerationTestable(KeyPairGenerator kpg, int keysize) {
this.kpg = kpg;
this.keysize = keysize;
@@ -42,7 +46,7 @@ public class KeyGenerationTestable implements Testable {
try {
if (spec != null) {
kpg.initialize(spec);
- } else {
+ } else if (keysize != 0) {
kpg.initialize(keysize);
}
} catch (InvalidAlgorithmParameterException e) {