sigs = lib.getECSigs();
- if (!eckas.isEmpty()) {
- System.out.println("\t\t- Signatures: " + String.join(",", sigs.stream().map(SignatureIdent::getName).collect(Collectors.toList())));
- }
- }
- }
+ private void test() {
+
+ }
+
+ /**
+ *
+ */
+ private void export() {
+
}
public static void main(String[] args) {
diff --git a/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java b/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java
index 22b03a4..c0d1e27 100644
--- a/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java
+++ b/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java
@@ -55,6 +55,8 @@ public class KeyAgreementIdent extends Ident {
}
public KeyAgreement getInstance(Provider provider) throws NoSuchAlgorithmException {
- return KeyAgreement.getInstance(name, provider);
+ KeyAgreement instance = KeyAgreement.getInstance(name, provider);
+ instance.getProvider();
+ return instance;
}
}
diff --git a/src/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java b/src/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java
index f806282..d0526f7 100644
--- a/src/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java
+++ b/src/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java
@@ -31,6 +31,8 @@ public class KeyPairGeneratorIdent extends Ident {
}
public KeyPairGenerator getInstance(Provider provider) throws NoSuchAlgorithmException {
- return KeyPairGenerator.getInstance(name, provider);
+ KeyPairGenerator instance = KeyPairGenerator.getInstance(name, provider);
+ instance.getProvider();
+ return instance;
}
}
diff --git a/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java b/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java
index dc554e2..c027bf1 100644
--- a/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java
+++ b/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java
@@ -79,6 +79,8 @@ public class SignatureIdent extends Ident {
}
public Signature getInstance(Provider provider) throws NoSuchAlgorithmException {
- return Signature.getInstance(name, provider);
+ Signature instance = Signature.getInstance(name, provider);
+ instance.getProvider();
+ return instance;
}
}
--
cgit v1.2.3-70-g09d2
From c7cffa5d408b0df4276bc27cc9206825ad81ddfa Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sun, 26 Nov 2017 19:39:57 +0100
Subject: Add export of default standalone lib params.
---
.../ectester/standalone/ECTesterStandalone.java | 48 ++++++++++++++++++----
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 741d81e..049626e 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -21,7 +21,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;
@@ -117,6 +117,8 @@ public class ECTesterStandalone {
actions.put("generate", generate);
Options exportOpts = new Options();
+ exportOpts.addOption(Option.builder("t").longOpt("type").hasArg().argName("type").optionalArg(false).desc("Set KeyPair object [type].").build());
+ exportOpts.addOption(Option.builder("b").longOpt("bits").hasArg().argName("n").optionalArg(false).desc("What size of curve to use.").build());
ParserOptions export = new ParserOptions(new DefaultParser(), exportOpts);
actions.put("export", export);
@@ -196,7 +198,7 @@ public class ECTesterStandalone {
} else {
KeyPairGenerator kpg = ident.getInstance(jlib.getProvider());
if (cli.hasOption("generate.bits")) {
- int bits = Integer.parseInt(cli.getOptionValue("generate.bits", "256"));
+ int bits = Integer.parseInt(cli.getOptionValue("generate.bits"));
kpg.initialize(bits);
} else if (cli.hasOption("generate.named-curve")) {
String curveName = cli.getOptionValue("generate.named-curve");
@@ -206,15 +208,12 @@ public class ECTesterStandalone {
return;
}
kpg.initialize(curve.toSpec());
- } else {
- kpg.initialize(256);
}
int amount = Integer.parseInt(cli.getOptionValue("generate.amount", "1"));
for (int i = 0; i < amount; ++i) {
KeyPair kp = kpg.genKeyPair();
ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate();
- ECPublicKey publicKey = (ECPublicKey) kp.getPublic();
System.out.println(privateKey);
}
}
@@ -231,8 +230,31 @@ public class ECTesterStandalone {
/**
*
*/
- private void export() {
-
+ private void export() throws NoSuchAlgorithmException {
+ if (cfg.selected instanceof JavaECLibrary) {
+ JavaECLibrary jlib = (JavaECLibrary) cfg.selected;
+ KeyPairGeneratorIdent ident = null;
+ String algo = cli.getOptionValue("export.type", "EC");
+ for (KeyPairGeneratorIdent kpIdent : jlib.getKPGs()) {
+ if (kpIdent.contains(algo)) {
+ ident = kpIdent;
+ break;
+ }
+ }
+ if (ident == null) {
+ throw new NoSuchAlgorithmException(algo);
+ } else {
+ KeyPairGenerator kpg = ident.getInstance(jlib.getProvider());
+ if (cli.hasOption("export.bits")) {
+ int bits = Integer.parseInt(cli.getOptionValue("export.bits"));
+ kpg.initialize(bits);
+ }
+ KeyPair kp = kpg.genKeyPair();
+ ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate();
+ ECParameterSpec params = privateKey.getParams();
+ System.out.println(params);
+ }
+ }
}
public static void main(String[] args) {
@@ -260,7 +282,17 @@ public class ECTesterStandalone {
}
if (cli.hasOption("generate.bits") && cli.hasOption("generate.named-curve")) {
- System.err.println("");
+ System.err.println("You can only specify bitsize or a named curve, nor both.");
+ return false;
+ }
+ } else if (cli.isNext("export")) {
+ if (!cli.hasArg(-1)) {
+ System.err.println("Missing library name argument.");
+ return false;
+ }
+
+ if (cli.hasOption("export.bits") && cli.hasOption("export.named-curve")) {
+ System.err.println("You can only specify bitsize or a named curve, nor both.");
return false;
}
}
--
cgit v1.2.3-70-g09d2
From 23bd6d8439e9e536d5de672a556211b896b9e98d Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sun, 26 Nov 2017 19:44:37 +0100
Subject: Fix usage printing args.
---
src/cz/crcs/ectester/common/cli/CLITools.java | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/cz/crcs/ectester/common/cli/CLITools.java b/src/cz/crcs/ectester/common/cli/CLITools.java
index 77b3794..91f121f 100644
--- a/src/cz/crcs/ectester/common/cli/CLITools.java
+++ b/src/cz/crcs/ectester/common/cli/CLITools.java
@@ -65,17 +65,20 @@ public class CLITools {
upw.print(" | ");
}
}
- Argument[] args = tp.getArgs().toArray(new Argument[tp.getArgs().size()]);
- String[] argss = new String[tp.getArgs().size()];
- for (int i = 0; i < args.length; ++i) {
- Argument arg = args[i];
- argss[i] = arg.isRequired() ? "<" + arg.getName() + ">" : "[" + arg.getName() + "]";
- }
- upw.print(String.join(" ", argss));
if (keys.length > 0 && !tp.isRequired()) {
upw.print(" ]");
}
+
+ Argument[] args = tp.getArgs().toArray(new Argument[tp.getArgs().size()]);
+ if (args.length > 0) {
+ String[] argss = new String[tp.getArgs().size()];
+ for (int i = 0; i < args.length; ++i) {
+ Argument arg = args[i];
+ argss[i] = arg.isRequired() ? "<" + arg.getName() + ">" : "[" + arg.getName() + "]";
+ }
+ upw.print(" " + String.join(" ", argss));
+ }
}
pw.println(sw.toString().replaceAll("usage:( )?", "").replace("\n", ""));
}
--
cgit v1.2.3-70-g09d2
From 83943c809c56c1856038b21fd91f50cc709310aa Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sun, 26 Nov 2017 23:27:07 +0100
Subject: Split Util class into a package.
---
src/cz/crcs/ectester/common/Util.java | 375 ---------------------
src/cz/crcs/ectester/common/ec/EC_Curve.java | 54 ++-
src/cz/crcs/ectester/common/ec/EC_Data.java | 31 +-
src/cz/crcs/ectester/common/ec/EC_KAResult.java | 4 +-
src/cz/crcs/ectester/common/ec/EC_Params.java | 24 +-
src/cz/crcs/ectester/common/util/ByteUtil.java | 122 +++++++
src/cz/crcs/ectester/common/util/CardUtil.java | 255 ++++++++++++++
src/cz/crcs/ectester/reader/CardMngr.java | 16 +-
src/cz/crcs/ectester/reader/ECTesterReader.java | 10 +-
src/cz/crcs/ectester/reader/command/Command.java | 18 +-
.../ectester/reader/output/ResponseWriter.java | 6 +-
.../crcs/ectester/reader/output/XMLTestWriter.java | 6 +-
.../ectester/reader/output/YAMLTestWriter.java | 6 +-
src/cz/crcs/ectester/reader/response/Response.java | 15 +-
.../crcs/ectester/reader/test/TestVectorSuite.java | 6 +-
.../ectester/standalone/ECTesterStandalone.java | 21 +-
.../standalone/test/KeyGenerationTestable.java | 10 +-
17 files changed, 528 insertions(+), 451 deletions(-)
delete mode 100644 src/cz/crcs/ectester/common/Util.java
create mode 100644 src/cz/crcs/ectester/common/util/ByteUtil.java
create mode 100644 src/cz/crcs/ectester/common/util/CardUtil.java
diff --git a/src/cz/crcs/ectester/common/Util.java b/src/cz/crcs/ectester/common/Util.java
deleted file mode 100644
index 0136493..0000000
--- a/src/cz/crcs/ectester/common/Util.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package cz.crcs.ectester.common;
-
-import cz.crcs.ectester.applet.ECTesterApplet;
-import cz.crcs.ectester.applet.EC_Consts;
-import javacard.framework.ISO7816;
-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 static String getSWSource(short sw) {
- switch (sw) {
- case ISO7816.SW_NO_ERROR:
- case ISO7816.SW_APPLET_SELECT_FAILED:
- case ISO7816.SW_BYTES_REMAINING_00:
- case ISO7816.SW_CLA_NOT_SUPPORTED:
- case ISO7816.SW_COMMAND_NOT_ALLOWED:
- case ISO7816.SW_CONDITIONS_NOT_SATISFIED:
- case ISO7816.SW_CORRECT_LENGTH_00:
- case ISO7816.SW_DATA_INVALID:
- case ISO7816.SW_FILE_FULL:
- case ISO7816.SW_FILE_INVALID:
- case ISO7816.SW_FILE_NOT_FOUND:
- case ISO7816.SW_FUNC_NOT_SUPPORTED:
- case ISO7816.SW_INCORRECT_P1P2:
- case ISO7816.SW_INS_NOT_SUPPORTED:
- case ISO7816.SW_LOGICAL_CHANNEL_NOT_SUPPORTED:
- case ISO7816.SW_RECORD_NOT_FOUND:
- case ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED:
- case ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED:
- case ISO7816.SW_UNKNOWN:
- case ISO7816.SW_WARNING_STATE_UNCHANGED:
- case ISO7816.SW_WRONG_DATA:
- case ISO7816.SW_WRONG_LENGTH:
- case ISO7816.SW_WRONG_P1P2:
- return "ISO";
- case CryptoException.ILLEGAL_VALUE:
- case CryptoException.UNINITIALIZED_KEY:
- case CryptoException.NO_SUCH_ALGORITHM:
- case CryptoException.INVALID_INIT:
- case CryptoException.ILLEGAL_USE:
- return "CryptoException";
- case ECTesterApplet.SW_SIG_VERIFY_FAIL:
- case ECTesterApplet.SW_DH_DHC_MISMATCH:
- case ECTesterApplet.SW_KEYPAIR_NULL:
- case ECTesterApplet.SW_KA_NULL:
- case ECTesterApplet.SW_SIGNATURE_NULL:
- case ECTesterApplet.SW_OBJECT_NULL:
- return "ECTesterApplet";
- default:
- return "?";
- }
- }
-
- public static String getSW(short sw) {
- String str;
- switch (sw) {
- case ISO7816.SW_APPLET_SELECT_FAILED:
- str = "APPLET_SELECT_FAILED";
- break;
- case ISO7816.SW_BYTES_REMAINING_00:
- str = "BYTES_REMAINING";
- break;
- case ISO7816.SW_CLA_NOT_SUPPORTED:
- str = "CLA_NOT_SUPPORTED";
- break;
- case ISO7816.SW_COMMAND_NOT_ALLOWED:
- str = "COMMAND_NOT_ALLOWED";
- break;
- case ISO7816.SW_CONDITIONS_NOT_SATISFIED:
- str = "CONDITIONS_NOT_SATISFIED";
- break;
- case ISO7816.SW_CORRECT_LENGTH_00:
- str = "CORRECT_LENGTH";
- break;
- case ISO7816.SW_DATA_INVALID:
- str = "DATA_INVALID";
- break;
- case ISO7816.SW_FILE_FULL:
- str = "FILE_FULL";
- break;
- case ISO7816.SW_FILE_INVALID:
- str = "FILE_INVALID";
- break;
- case ISO7816.SW_FILE_NOT_FOUND:
- str = "FILE_NOT_FOUND";
- break;
- case ISO7816.SW_FUNC_NOT_SUPPORTED:
- str = "FUNC_NOT_SUPPORTED";
- break;
- case ISO7816.SW_INCORRECT_P1P2:
- str = "INCORRECT_P1P2";
- break;
- case ISO7816.SW_INS_NOT_SUPPORTED:
- str = "INS_NOT_SUPPORTED";
- break;
- case ISO7816.SW_LOGICAL_CHANNEL_NOT_SUPPORTED:
- str = "LOGICAL_CHANNEL_NOT_SUPPORTED";
- break;
- case ISO7816.SW_RECORD_NOT_FOUND:
- str = "RECORD_NOT_FOUND";
- break;
- case ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED:
- str = "SECURE_MESSAGING_NOT_SUPPORTED";
- break;
- case ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED:
- str = "SECURITY_STATUS_NOT_SATISFIED";
- break;
- case ISO7816.SW_UNKNOWN:
- str = "UNKNOWN";
- break;
- case ISO7816.SW_WARNING_STATE_UNCHANGED:
- str = "WARNING_STATE_UNCHANGED";
- break;
- case ISO7816.SW_WRONG_DATA:
- str = "WRONG_DATA";
- break;
- case ISO7816.SW_WRONG_LENGTH:
- str = "WRONG_LENGTH";
- break;
- case ISO7816.SW_WRONG_P1P2:
- str = "WRONG_P1P2";
- break;
- case CryptoException.ILLEGAL_VALUE:
- str = "ILLEGAL_VALUE";
- break;
- case CryptoException.UNINITIALIZED_KEY:
- str = "UNINITIALIZED_KEY";
- break;
- case CryptoException.NO_SUCH_ALGORITHM:
- str = "NO_SUCH_ALG";
- break;
- case CryptoException.INVALID_INIT:
- str = "INVALID_INIT";
- break;
- case CryptoException.ILLEGAL_USE:
- str = "ILLEGAL_USE";
- break;
- case ECTesterApplet.SW_SIG_VERIFY_FAIL:
- str = "SIG_VERIFY_FAIL";
- break;
- case ECTesterApplet.SW_DH_DHC_MISMATCH:
- str = "DH_DHC_MISMATCH";
- break;
- case ECTesterApplet.SW_KEYPAIR_NULL:
- str = "KEYPAIR_NULL";
- break;
- case ECTesterApplet.SW_KA_NULL:
- str = "KA_NULL";
- break;
- case ECTesterApplet.SW_SIGNATURE_NULL:
- str = "SIGNATURE_NULL";
- break;
- case ECTesterApplet.SW_OBJECT_NULL:
- str = "OBJECT_NULL";
- break;
- default:
- str = "unknown";
- break;
- }
- return str;
- }
-
- public static String getSWString(short sw) {
- if (sw == ISO7816.SW_NO_ERROR) {
- return "OK (0x9000)";
- } else {
- String str = getSW(sw);
- return String.format("fail (%s, 0x%04x)", str, sw);
- }
- }
-
- public static String getCorruption(short corruptionType) {
- String corrupt;
- switch (corruptionType) {
- case EC_Consts.CORRUPTION_NONE:
- corrupt = "NONE";
- break;
- case EC_Consts.CORRUPTION_FIXED:
- corrupt = "FIXED";
- break;
- case EC_Consts.CORRUPTION_ONE:
- corrupt = "ONE";
- break;
- case EC_Consts.CORRUPTION_ZERO:
- corrupt = "ZERO";
- break;
- case EC_Consts.CORRUPTION_ONEBYTERANDOM:
- corrupt = "ONE_BYTE_RANDOM";
- break;
- case EC_Consts.CORRUPTION_FULLRANDOM:
- corrupt = "FULL_RANDOM";
- break;
- case EC_Consts.CORRUPTION_INCREMENT:
- corrupt = "INCREMENT";
- break;
- case EC_Consts.CORRUPTION_INFINITY:
- corrupt = "INFINITY";
- break;
- case EC_Consts.CORRUPTION_COMPRESS:
- corrupt = "COMPRESSED";
- break;
- case EC_Consts.CORRUPTION_MAX:
- corrupt = "MAX";
- break;
- default:
- corrupt = "unknown";
- break;
- }
- return corrupt;
- }
-
- public static String getKA(byte ka) {
- String algo = "";
- if ((ka & EC_Consts.KA_ECDH) != 0 || ka == EC_Consts.KA_ANY) {
- algo += "ECDH";
- }
- if (ka == EC_Consts.KA_BOTH) {
- algo += "+";
- } else if (ka == EC_Consts.KA_ANY) {
- algo += "/";
- }
- if ((ka & EC_Consts.KA_ECDHC) != 0 || ka == EC_Consts.KA_ANY) {
- algo += "ECDHC";
- }
- return algo;
- }
-
- public static String getKATypeString(byte kaType) {
- String kaTypeString;
- 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;
- }
-}
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.
- *
+ *
* 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 {
@@ -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 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/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java
new file mode 100644
index 0000000..a94c773
--- /dev/null
+++ b/src/cz/crcs/ectester/common/util/CardUtil.java
@@ -0,0 +1,255 @@
+package cz.crcs.ectester.common.util;
+
+import cz.crcs.ectester.applet.ECTesterApplet;
+import cz.crcs.ectester.applet.EC_Consts;
+import javacard.framework.ISO7816;
+import javacard.security.CryptoException;
+
+import static cz.crcs.ectester.applet.ECTesterApplet.*;
+
+public class CardUtil {
+ public static String getSWSource(short sw) {
+ switch (sw) {
+ case ISO7816.SW_NO_ERROR:
+ case ISO7816.SW_APPLET_SELECT_FAILED:
+ case ISO7816.SW_BYTES_REMAINING_00:
+ case ISO7816.SW_CLA_NOT_SUPPORTED:
+ case ISO7816.SW_COMMAND_NOT_ALLOWED:
+ case ISO7816.SW_CONDITIONS_NOT_SATISFIED:
+ case ISO7816.SW_CORRECT_LENGTH_00:
+ case ISO7816.SW_DATA_INVALID:
+ case ISO7816.SW_FILE_FULL:
+ case ISO7816.SW_FILE_INVALID:
+ case ISO7816.SW_FILE_NOT_FOUND:
+ case ISO7816.SW_FUNC_NOT_SUPPORTED:
+ case ISO7816.SW_INCORRECT_P1P2:
+ case ISO7816.SW_INS_NOT_SUPPORTED:
+ case ISO7816.SW_LOGICAL_CHANNEL_NOT_SUPPORTED:
+ case ISO7816.SW_RECORD_NOT_FOUND:
+ case ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED:
+ case ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED:
+ case ISO7816.SW_UNKNOWN:
+ case ISO7816.SW_WARNING_STATE_UNCHANGED:
+ case ISO7816.SW_WRONG_DATA:
+ case ISO7816.SW_WRONG_LENGTH:
+ case ISO7816.SW_WRONG_P1P2:
+ return "ISO";
+ case CryptoException.ILLEGAL_VALUE:
+ case CryptoException.UNINITIALIZED_KEY:
+ case CryptoException.NO_SUCH_ALGORITHM:
+ case CryptoException.INVALID_INIT:
+ case CryptoException.ILLEGAL_USE:
+ return "CryptoException";
+ case ECTesterApplet.SW_SIG_VERIFY_FAIL:
+ case ECTesterApplet.SW_DH_DHC_MISMATCH:
+ case ECTesterApplet.SW_KEYPAIR_NULL:
+ case ECTesterApplet.SW_KA_NULL:
+ case ECTesterApplet.SW_SIGNATURE_NULL:
+ case ECTesterApplet.SW_OBJECT_NULL:
+ return "ECTesterApplet";
+ default:
+ return "?";
+ }
+ }
+
+ public static String getSW(short sw) {
+ String str;
+ switch (sw) {
+ case ISO7816.SW_APPLET_SELECT_FAILED:
+ str = "APPLET_SELECT_FAILED";
+ break;
+ case ISO7816.SW_BYTES_REMAINING_00:
+ str = "BYTES_REMAINING";
+ break;
+ case ISO7816.SW_CLA_NOT_SUPPORTED:
+ str = "CLA_NOT_SUPPORTED";
+ break;
+ case ISO7816.SW_COMMAND_NOT_ALLOWED:
+ str = "COMMAND_NOT_ALLOWED";
+ break;
+ case ISO7816.SW_CONDITIONS_NOT_SATISFIED:
+ str = "CONDITIONS_NOT_SATISFIED";
+ break;
+ case ISO7816.SW_CORRECT_LENGTH_00:
+ str = "CORRECT_LENGTH";
+ break;
+ case ISO7816.SW_DATA_INVALID:
+ str = "DATA_INVALID";
+ break;
+ case ISO7816.SW_FILE_FULL:
+ str = "FILE_FULL";
+ break;
+ case ISO7816.SW_FILE_INVALID:
+ str = "FILE_INVALID";
+ break;
+ case ISO7816.SW_FILE_NOT_FOUND:
+ str = "FILE_NOT_FOUND";
+ break;
+ case ISO7816.SW_FUNC_NOT_SUPPORTED:
+ str = "FUNC_NOT_SUPPORTED";
+ break;
+ case ISO7816.SW_INCORRECT_P1P2:
+ str = "INCORRECT_P1P2";
+ break;
+ case ISO7816.SW_INS_NOT_SUPPORTED:
+ str = "INS_NOT_SUPPORTED";
+ break;
+ case ISO7816.SW_LOGICAL_CHANNEL_NOT_SUPPORTED:
+ str = "LOGICAL_CHANNEL_NOT_SUPPORTED";
+ break;
+ case ISO7816.SW_RECORD_NOT_FOUND:
+ str = "RECORD_NOT_FOUND";
+ break;
+ case ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED:
+ str = "SECURE_MESSAGING_NOT_SUPPORTED";
+ break;
+ case ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED:
+ str = "SECURITY_STATUS_NOT_SATISFIED";
+ break;
+ case ISO7816.SW_UNKNOWN:
+ str = "UNKNOWN";
+ break;
+ case ISO7816.SW_WARNING_STATE_UNCHANGED:
+ str = "WARNING_STATE_UNCHANGED";
+ break;
+ case ISO7816.SW_WRONG_DATA:
+ str = "WRONG_DATA";
+ break;
+ case ISO7816.SW_WRONG_LENGTH:
+ str = "WRONG_LENGTH";
+ break;
+ case ISO7816.SW_WRONG_P1P2:
+ str = "WRONG_P1P2";
+ break;
+ case CryptoException.ILLEGAL_VALUE:
+ str = "ILLEGAL_VALUE";
+ break;
+ case CryptoException.UNINITIALIZED_KEY:
+ str = "UNINITIALIZED_KEY";
+ break;
+ case CryptoException.NO_SUCH_ALGORITHM:
+ str = "NO_SUCH_ALG";
+ break;
+ case CryptoException.INVALID_INIT:
+ str = "INVALID_INIT";
+ break;
+ case CryptoException.ILLEGAL_USE:
+ str = "ILLEGAL_USE";
+ break;
+ case ECTesterApplet.SW_SIG_VERIFY_FAIL:
+ str = "SIG_VERIFY_FAIL";
+ break;
+ case ECTesterApplet.SW_DH_DHC_MISMATCH:
+ str = "DH_DHC_MISMATCH";
+ break;
+ case ECTesterApplet.SW_KEYPAIR_NULL:
+ str = "KEYPAIR_NULL";
+ break;
+ case ECTesterApplet.SW_KA_NULL:
+ str = "KA_NULL";
+ break;
+ case ECTesterApplet.SW_SIGNATURE_NULL:
+ str = "SIGNATURE_NULL";
+ break;
+ case ECTesterApplet.SW_OBJECT_NULL:
+ str = "OBJECT_NULL";
+ break;
+ default:
+ str = "unknown";
+ break;
+ }
+ return str;
+ }
+
+ public static String getSWString(short sw) {
+ if (sw == ISO7816.SW_NO_ERROR) {
+ return "OK (0x9000)";
+ } else {
+ String str = getSW(sw);
+ return String.format("fail (%s, 0x%04x)", str, sw);
+ }
+ }
+
+ public static String getCorruption(short corruptionType) {
+ String corrupt;
+ switch (corruptionType) {
+ case EC_Consts.CORRUPTION_NONE:
+ corrupt = "NONE";
+ break;
+ case EC_Consts.CORRUPTION_FIXED:
+ corrupt = "FIXED";
+ break;
+ case EC_Consts.CORRUPTION_ONE:
+ corrupt = "ONE";
+ break;
+ case EC_Consts.CORRUPTION_ZERO:
+ corrupt = "ZERO";
+ break;
+ case EC_Consts.CORRUPTION_ONEBYTERANDOM:
+ corrupt = "ONE_BYTE_RANDOM";
+ break;
+ case EC_Consts.CORRUPTION_FULLRANDOM:
+ corrupt = "FULL_RANDOM";
+ break;
+ case EC_Consts.CORRUPTION_INCREMENT:
+ corrupt = "INCREMENT";
+ break;
+ case EC_Consts.CORRUPTION_INFINITY:
+ corrupt = "INFINITY";
+ break;
+ case EC_Consts.CORRUPTION_COMPRESS:
+ corrupt = "COMPRESSED";
+ break;
+ case EC_Consts.CORRUPTION_MAX:
+ corrupt = "MAX";
+ break;
+ default:
+ corrupt = "unknown";
+ break;
+ }
+ return corrupt;
+ }
+
+ public static String getKA(byte ka) {
+ String algo = "";
+ if ((ka & EC_Consts.KA_ECDH) != 0 || ka == EC_Consts.KA_ANY) {
+ algo += "ECDH";
+ }
+ if (ka == EC_Consts.KA_BOTH) {
+ algo += "+";
+ } else if (ka == EC_Consts.KA_ANY) {
+ algo += "/";
+ }
+ if ((ka & EC_Consts.KA_ECDHC) != 0 || ka == EC_Consts.KA_ANY) {
+ algo += "ECDHC";
+ }
+ return algo;
+ }
+
+ public static String getKATypeString(byte kaType) {
+ String kaTypeString;
+ 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;
+ }
+}
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 commandObject(Command c) {
Map commandObj = new HashMap<>();
- commandObj.put("apdu", Util.bytesToHex(c.getAPDU().getBytes()));
+ commandObj.put("apdu", ByteUtil.bytesToHex(c.getAPDU().getBytes()));
return commandObj;
}
private Map responseObject(Response r) {
Map 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 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) {
--
cgit v1.2.3-70-g09d2
From 7737039d8c1ad743ed1f5dc5e40224e297acd08d Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sun, 26 Nov 2017 23:50:00 +0100
Subject: Export generated keys in ANSI X9.62 uncompressed format.
---
src/cz/crcs/ectester/common/util/CardUtil.java | 4 +++
src/cz/crcs/ectester/common/util/ECUtil.java | 37 ++++++++++++++++++++++
.../ectester/standalone/ECTesterStandalone.java | 5 +--
3 files changed, 44 insertions(+), 2 deletions(-)
create mode 100644 src/cz/crcs/ectester/common/util/ECUtil.java
diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java
index a94c773..edcb510 100644
--- a/src/cz/crcs/ectester/common/util/CardUtil.java
+++ b/src/cz/crcs/ectester/common/util/CardUtil.java
@@ -7,6 +7,10 @@ import javacard.security.CryptoException;
import static cz.crcs.ectester.applet.ECTesterApplet.*;
+/**
+ * @author Petr Svenda petr@svenda.com
+ * @author Jan Jancar johny@neuromancer.sk
+ */
public class CardUtil {
public static String getSWSource(short sw) {
switch (sw) {
diff --git a/src/cz/crcs/ectester/common/util/ECUtil.java b/src/cz/crcs/ectester/common/util/ECUtil.java
new file mode 100644
index 0000000..713effe
--- /dev/null
+++ b/src/cz/crcs/ectester/common/util/ECUtil.java
@@ -0,0 +1,37 @@
+package cz.crcs.ectester.common.util;
+
+import java.math.BigInteger;
+import java.security.spec.ECPoint;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class ECUtil {
+ public static byte[] toX962Compressed(ECPoint point) {
+ if (point.equals(ECPoint.POINT_INFINITY)) {
+ return new byte[]{0};
+ }
+ byte[] x = point.getAffineX().toByteArray();
+ byte marker = (byte) (0x02 | point.getAffineY().mod(BigInteger.valueOf(2)).byteValue());
+ return ByteUtil.concatenate(new byte[]{marker}, x);
+ }
+
+ public static byte[] toX962Uncompressed(ECPoint point) {
+ if (point.equals(ECPoint.POINT_INFINITY)) {
+ return new byte[]{0};
+ }
+ byte[] x = point.getAffineX().toByteArray();
+ byte[] y = point.getAffineY().toByteArray();
+ return ByteUtil.concatenate(new byte[]{0x04}, x, y);
+ }
+
+ public static byte[] toX962Hybrid(ECPoint point) {
+ if (point.equals(ECPoint.POINT_INFINITY)) {
+ return new byte[]{0};
+ }
+ byte[] x = point.getAffineX().toByteArray();
+ byte[] y = point.getAffineY().toByteArray();
+ byte marker = (byte) (0x06 | point.getAffineY().mod(BigInteger.valueOf(2)).byteValue());
+ return ByteUtil.concatenate(new byte[]{marker}, x, y);
+ }
+}
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 9f100d0..af01a46 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -3,6 +3,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.common.util.ECUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent;
@@ -221,8 +222,8 @@ public class ECTesterStandalone {
ECPublicKey publicKey = (ECPublicKey) kp.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate();
- String pub = ByteUtil.bytesToHex(publicKey.getEncoded(), false);
- String priv = ByteUtil.bytesToHex(privateKey.getEncoded(), false);
+ String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(publicKey.getW()), false);
+ String priv = ByteUtil.bytesToHex(privateKey.getS().toByteArray(), false);
System.out.println(String.format("%d;%d;%s;%s", i, elapsed / 1000000, pub, priv));
}
}
--
cgit v1.2.3-70-g09d2
From 6841b6bbbbbed114cd4f5444d10181439cadba8e Mon Sep 17 00:00:00 2001
From: J08nY
Date: Mon, 27 Nov 2017 00:09:05 +0100
Subject: Export default lib curves in CSV.
---
src/cz/crcs/ectester/common/ec/EC_Curve.java | 9 ++++++---
src/cz/crcs/ectester/standalone/ECTesterStandalone.java | 4 ++--
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/cz/crcs/ectester/common/ec/EC_Curve.java b/src/cz/crcs/ectester/common/ec/EC_Curve.java
index 19228dc..173fd29 100644
--- a/src/cz/crcs/ectester/common/ec/EC_Curve.java
+++ b/src/cz/crcs/ectester/common/ec/EC_Curve.java
@@ -95,12 +95,12 @@ public class EC_Curve extends EC_Params {
byte fieldType;
if (field instanceof ECFieldFp) {
ECFieldFp primeField = (ECFieldFp) field;
- params = new byte[5][];
+ params = new byte[7][];
params[paramIndex++] = primeField.getP().toByteArray();
fieldType = KeyPair.ALG_EC_FP;
} else if (field instanceof ECFieldF2m) {
ECFieldF2m binaryField = (ECFieldF2m) field;
- params = new byte[8][];
+ params = new byte[10][];
params[paramIndex] = new byte[2];
ByteUtil.setShort(params[paramIndex++], 0, (short) binaryField.getM());
int[] powers = binaryField.getMidTermsOfReductionPolynomial();
@@ -110,11 +110,14 @@ public class EC_Curve extends EC_Params {
}
fieldType = KeyPair.ALG_EC_F2M;
} else {
- throw new IllegalArgumentException("ECParameterSpec with an unknnown field.");
+ throw new IllegalArgumentException("ECParameterSpec with an unknown field.");
}
ECPoint generator = spec.getGenerator();
+ params[paramIndex++] = curve.getA().toByteArray();
+ params[paramIndex++] = curve.getB().toByteArray();
+
params[paramIndex++] = generator.getAffineX().toByteArray();
params[paramIndex++] = generator.getAffineY().toByteArray();
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index af01a46..76b98ce 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -240,7 +240,7 @@ public class ECTesterStandalone {
/**
*
*/
- private void export() throws NoSuchAlgorithmException {
+ private void export() throws NoSuchAlgorithmException, IOException {
if (cfg.selected instanceof JavaECLibrary) {
JavaECLibrary jlib = (JavaECLibrary) cfg.selected;
KeyPairGeneratorIdent ident = null;
@@ -264,7 +264,7 @@ public class ECTesterStandalone {
ECParameterSpec params = privateKey.getParams();
System.out.println(params);
EC_Curve curve = EC_Curve.fromSpec(params);
- System.out.println(curve);
+ curve.writeCSV(System.out);
}
}
}
--
cgit v1.2.3-70-g09d2
From 9bce1e13ec136c06650868acf3438e789e366d5f Mon Sep 17 00:00:00 2001
From: J08nY
Date: Mon, 27 Nov 2017 23:19:48 +0100
Subject: Add a basic NativeECLibrary interface.
---
build-standalone.xml | 5 +
nbproject/reader/project.properties | 2 +-
nbproject/standalone/project.properties | 2 +-
.../ectester/standalone/ECTesterStandalone.java | 10 +-
.../ectester/standalone/libs/BouncyCastleLib.java | 2 +-
.../crcs/ectester/standalone/libs/CECLibrary.java | 31 -----
.../ectester/standalone/libs/JavaECLibrary.java | 86 --------------
.../ectester/standalone/libs/NativeECLibrary.java | 131 +++++++++++++++++++++
.../standalone/libs/ProviderECLibrary.java | 90 ++++++++++++++
src/cz/crcs/ectester/standalone/libs/SunECLib.java | 2 +-
.../crcs/ectester/standalone/libs/TomcryptLib.java | 16 +++
src/cz/crcs/ectester/standalone/libs/native.h | 21 ++++
12 files changed, 272 insertions(+), 126 deletions(-)
delete mode 100644 src/cz/crcs/ectester/standalone/libs/CECLibrary.java
delete mode 100644 src/cz/crcs/ectester/standalone/libs/JavaECLibrary.java
create mode 100644 src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
create mode 100644 src/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java
create mode 100644 src/cz/crcs/ectester/standalone/libs/TomcryptLib.java
create mode 100644 src/cz/crcs/ectester/standalone/libs/native.h
diff --git a/build-standalone.xml b/build-standalone.xml
index 0ba7f93..05dc174 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -75,4 +75,9 @@