diff options
| author | quapka | 2024-06-21 16:31:37 +0200 |
|---|---|---|
| committer | quapka | 2024-06-21 16:31:37 +0200 |
| commit | ada61982cc70a2c72a6fc765dc9b4a9c01202a27 (patch) | |
| tree | d92bee42106e850d4da90ad7174ac609ca175eda /standalone/src/main/java | |
| parent | c051ef2ecfa92723d6dea675ac8c345be92cf165 (diff) | |
| parent | c112d3e49bbbbf33cc70d12d196e109543c19a3c (diff) | |
| download | ECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.tar.gz ECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.tar.zst ECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.zip | |
Merge branch 'master' into build-with-nix
Diffstat (limited to 'standalone/src/main/java')
27 files changed, 572 insertions, 219 deletions
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index c702dee..e6d8188 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -36,10 +36,9 @@ import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; import cz.crcs.ectester.standalone.consts.SignatureIdent; import cz.crcs.ectester.standalone.libs.*; +import cz.crcs.ectester.standalone.libs.jni.SignalException; +import cz.crcs.ectester.standalone.libs.jni.TimeoutException; import cz.crcs.ectester.standalone.output.FileTestWriter; -import cz.crcs.ectester.standalone.output.TextTestWriter; -import cz.crcs.ectester.standalone.output.XMLTestWriter; -import cz.crcs.ectester.standalone.output.YAMLTestWriter; import cz.crcs.ectester.standalone.test.suites.*; import org.apache.commons.cli.*; @@ -55,8 +54,7 @@ import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.security.*; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; +import java.security.interfaces.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; @@ -105,8 +103,13 @@ public class ECTesterStandalone { reqs.toFile().mkdirs(); if (!System.getProperty("os.name").startsWith("Windows")) { - FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_timing.so", reqs.resolve("lib_timing.so")); + FileUtil.write(LIB_RESOURCE_DIR + "lib_timing.so", reqs.resolve("lib_timing.so")); System.load(reqs.resolve("lib_timing.so").toString()); + + FileUtil.write(LIB_RESOURCE_DIR + "lib_csignals.so", reqs.resolve("lib_csignals.so")); + System.load(reqs.resolve("lib_csignals.so").toString()); + FileUtil.write(LIB_RESOURCE_DIR + "lib_cppsignals.so", reqs.resolve("lib_cppsignals.so")); + System.load(reqs.resolve("lib_cppsignals.so").toString()); } List<ProviderECLibrary> libObjects = new LinkedList<>(); @@ -133,16 +136,6 @@ public class ECTesterStandalone { } libs = libObjects.toArray(new ProviderECLibrary[0]); - //TODO: push this further down to only initialize if necessary. - // and only initialize the chosen lib (so give libs a name in Java only) - for (ECLibrary lib : libs) { - try { - lib.initialize(); - } catch (Exception ex) { - System.err.println(ex.getMessage()); - } - } - cfg = new Config(libs); if (!cfg.readOptions(cli)) { return; @@ -299,26 +292,36 @@ public class ECTesterStandalone { */ private void listLibraries() { for (ProviderECLibrary lib : libs) { - if (lib.isInitialized() && (cfg.selected == null || lib == cfg.selected)) { + if (cfg.selected == null || lib == cfg.selected) { + try { + if (!lib.initialize()) { + continue; + } + } catch (Exception ex) { + System.err.println("Error initializing " + lib.fullName()); + System.err.println(ex.getMessage()); + continue; + } + System.out.println("\t- " + Colors.bold(lib.name())); System.out.println(Colors.bold("\t\t- Fullname: ") + lib.getProvider().getName()); System.out.println(Colors.bold("\t\t- Version: ") + lib.getProvider().getVersionStr()); System.out.println(Colors.bold("\t\t- Supports native timing: ") + lib.getNativeTimingSupport().toString()); Set<KeyPairGeneratorIdent> kpgs = lib.getKPGs(); if (!kpgs.isEmpty()) { - System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + kpgs.stream().map(KeyPairGeneratorIdent::getName).collect(Collectors.joining(", "))); + System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + kpgs.stream().map(KeyPairGeneratorIdent::getName).sorted().collect(Collectors.joining(", "))); } Set<KeyAgreementIdent> eckas = lib.getKAs(); if (!eckas.isEmpty()) { - System.out.println(Colors.bold("\t\t- KeyAgreements: ") + eckas.stream().map(KeyAgreementIdent::getName).collect(Collectors.joining(", "))); + System.out.println(Colors.bold("\t\t- KeyAgreements: ") + eckas.stream().map(KeyAgreementIdent::getName).sorted().collect(Collectors.joining(", "))); } Set<SignatureIdent> sigs = lib.getSigs(); if (!sigs.isEmpty()) { - System.out.println(Colors.bold("\t\t- Signatures: ") + sigs.stream().map(SignatureIdent::getName).collect(Collectors.joining(", "))); + System.out.println(Colors.bold("\t\t- Signatures: ") + sigs.stream().map(SignatureIdent::getName).sorted().collect(Collectors.joining(", "))); } Set<String> curves = lib.getCurves(); if (!curves.isEmpty()) { - System.out.println(Colors.bold("\t\t- Curves: ") + String.join(", ", curves)); + System.out.println(Colors.bold("\t\t- Curves: ") + curves.stream().sorted().collect(Collectors.joining(", "))); } System.out.println(); } @@ -458,8 +461,8 @@ public class ECTesterStandalone { other = kpg.genKeyPair(); } - ECPrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdh.named-private"), cli.getOptionValue("ecdh.private"), spec); - ECPublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdh.named-public"), cli.getOptionValue("ecdh.public"), spec); + PrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdh.named-private"), cli.getOptionValue("ecdh.private"), spec); + PublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdh.named-public"), cli.getOptionValue("ecdh.public"), spec); int amount = Integer.parseInt(cli.getOptionValue("ecdh.amount", "1")); for (int i = 0; i < amount || amount == 0; ++i) { @@ -471,11 +474,11 @@ public class ECTesterStandalone { } if (!cli.hasOption("ecdh.named-private") && !cli.hasOption("ecdh.private")) { - privkey = (ECPrivateKey) one.getPrivate(); + privkey = one.getPrivate(); } if (!cli.hasOption("ecdh.named-public") && !cli.hasOption("ecdh.public")) { - pubkey = (ECPublicKey) other.getPublic(); + pubkey = other.getPublic(); } long elapsed = -System.nanoTime(); @@ -501,8 +504,8 @@ public class ECTesterStandalone { } ka = kaIdent.getInstance(lib.getProvider()); - String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(pubkey.getW(), pubkey.getParams()), false); - String priv = ByteUtil.bytesToHex(privkey.getS().toByteArray(), false); + String pub = ByteUtil.bytesToHex(ECUtil.pubkeyToBytes(pubkey), false); + String priv = ByteUtil.bytesToHex(ECUtil.privkeyToBytes(privkey), false); String dh = ByteUtil.bytesToHex(result, false); out.printf("%d;%d;%s;%s;%s%n", i, elapsed, pub, priv, dh); } @@ -605,17 +608,17 @@ public class ECTesterStandalone { String hashAlgoOut = sigIdent.getHashAlgo() != null ? String.format("[%s]", sigIdent.getHashAlgo()) : ""; out.printf("index;signTime[%s];verifyTime[%s];data;pubW;privS;signature%s;nonce;verified%n", timeUnit, timeUnit, hashAlgoOut); - ECPrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdsa.named-private"), cli.getOptionValue("ecdsa.private"), spec); - ECPublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdsa.named-public"), cli.getOptionValue("ecdsa.public"), spec); + PrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdsa.named-private"), cli.getOptionValue("ecdsa.private"), spec); + PublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdsa.named-public"), cli.getOptionValue("ecdsa.public"), spec); KeyPair one; if (cli.hasOption("ecdsa.fixed")) { one = kpg.genKeyPair(); if (!cli.hasOption("ecdsa.named-private")) { - privkey = (ECPrivateKey) one.getPrivate(); + privkey = one.getPrivate(); } if (!cli.hasOption("ecdsa.named-public")) { - pubkey = (ECPublicKey) one.getPublic(); + pubkey = one.getPublic(); } } @@ -626,10 +629,10 @@ public class ECTesterStandalone { one = kpg.genKeyPair(); if (!cli.hasOption("ecdsa.named-private")) { - privkey = (ECPrivateKey) one.getPrivate(); + privkey = one.getPrivate(); } if (!cli.hasOption("ecdsa.named-public")) { - pubkey = (ECPublicKey) one.getPublic(); + pubkey = one.getPublic(); } } @@ -653,27 +656,31 @@ public class ECTesterStandalone { verifyTime = lib.getLastNativeTiming(); } - String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(pubkey.getW(), pubkey.getParams()), false); - String priv = ByteUtil.bytesToHex(privkey.getS().toByteArray(), false); + String pub = ByteUtil.bytesToHex(ECUtil.pubkeyToBytes(pubkey), false); + String priv = ByteUtil.bytesToHex(ECUtil.privkeyToBytes(privkey), false); String sign = ByteUtil.bytesToHex(signature, false); String k = ""; - ECParameterSpec kSpec = spec; - if (kSpec == null) { - kSpec = privkey.getParams(); - } - if (kSpec != null) { - // Parse the types out of SignatureIdent. - String hashAlgo = sigIdent.getHashAlgo(); - String sigType = sigIdent.getSigType(); - if (sigType == null) { - sigType = sigIdent.toString(); + if (privkey instanceof ECPrivateKey) { + ECPrivateKey ecPrivateKey = (ECPrivateKey) privkey; + ECParameterSpec kSpec = spec; + if (kSpec == null) { + kSpec = ecPrivateKey.getParams(); } + if (kSpec != null) { + // Parse the types out of SignatureIdent. + String hashAlgo = sigIdent.getHashAlgo(); + String sigType = sigIdent.getSigType(); + if (sigType == null) { + sigType = sigIdent.toString(); + } - BigInteger kValue = ECUtil.recoverSignatureNonce(signature, data, privkey.getS(), kSpec, hashAlgo, sigType); - if (kValue != null) { - k = ByteUtil.bytesToHex(kValue.toByteArray(), false); + BigInteger kValue = ECUtil.recoverSignatureNonce(signature, data, ecPrivateKey.getS(), kSpec, hashAlgo, sigType); + if (kValue != null) { + k = ByteUtil.bytesToHex(kValue.toByteArray(), false); + } } } + out.printf("%d;%d;%d;%s;%s;%s;%s;%s;%d%n", i, signTime, verifyTime, dataString, pub, priv, sign, k, verified ? 1 : 0); } @@ -739,16 +746,31 @@ public class ECTesterStandalone { int amount = Integer.parseInt(cli.getOptionValue("generate.amount", "1")); for (int i = 0; i < amount || amount == 0; ++i) { long elapsed = -System.nanoTime(); - KeyPair kp = kpg.genKeyPair(); + KeyPair kp; + try { + kp = kpg.genKeyPair(); + } catch (SignalException exc) { + System.err.println(exc.getSigInfo()); + continue; + } catch (TimeoutException exc) { + System.err.println(exc); + continue; + } elapsed += System.nanoTime(); if (!lib.getNativeTimingSupport().isEmpty()) { elapsed = lib.getLastNativeTiming(); } - ECPublicKey publicKey = (ECPublicKey) kp.getPublic(); - ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate(); - - String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(publicKey.getW(), publicKey.getParams()), false); - String priv = ByteUtil.bytesToHex(privateKey.getS().toByteArray(), false); + PublicKey pubkey = kp.getPublic(); + PrivateKey privkey = kp.getPrivate(); + byte[] pubBytes = ECUtil.pubkeyToBytes(pubkey); + byte[] privBytes = ECUtil.privkeyToBytes(privkey); + String pub = ByteUtil.bytesToHex(pubBytes, false); + String priv = ByteUtil.bytesToHex(privBytes, false); + if (pubBytes == null || privBytes == null) { + System.err.println(pubkey.getClass().getCanonicalName()); + System.err.println(privkey.getClass().getCanonicalName()); + break; + } out.printf("%d;%d;%s;%s%n", i, elapsed, pub, priv); } @@ -763,8 +785,40 @@ public class ECTesterStandalone { private void test() throws TestException, ParserConfigurationException, FileNotFoundException { TestWriter writer = new FileTestWriter(cli.getOptionValue("test.format", "text"), !cli.hasOption("test.quiet"), cli.getOptionValues("test.output")); StandaloneTestSuite suite; + String suiteOpt = cli.getArg(0) != null ? cli.getArg(0).toLowerCase() : "default"; + String testSuite; + int testFrom; + int testTo; + if (suiteOpt.contains(":")) { + String[] parts = suiteOpt.split(":"); + if (parts.length < 2 || parts.length > 3) { + System.err.println("Invalid test suite selection."); + return; + } + testSuite = parts[0]; + try { + testFrom = Integer.parseInt(parts[1]); + } catch (NumberFormatException nfe) { + System.err.println("Invalid test_from number: " + parts[1] + "."); + return; + } + if (parts.length == 3) { + try { + testTo = Integer.parseInt(parts[2]); + } catch (NumberFormatException nfe) { + System.err.println("Invalid test_to number: " + parts[2] + "."); + return; + } + } else { + testTo = -1; + } + } else { + testSuite = suiteOpt; + testFrom = 0; + testTo = -1; + } - switch (cli.getArg(0).toLowerCase()) { + switch (testSuite) { case "test-vectors": suite = new StandaloneTestVectorSuite(writer, cfg, cli); break; @@ -798,12 +852,12 @@ public class ECTesterStandalone { case "performance": suite = new StandalonePerformanceSuite(writer, cfg, cli); break; - case "default": default: suite = new StandaloneDefaultSuite(writer, cfg, cli); + break; } - suite.run(); + suite.run(testFrom, testTo); } /** @@ -888,7 +942,7 @@ public class ECTesterStandalone { if (libraryName != null) { List<ProviderECLibrary> matchedLibs = new LinkedList<>(); for (ProviderECLibrary lib : libs) { - if (lib.isInitialized() && lib.name().toLowerCase().contains(libraryName.toLowerCase())) { + if (lib.name().toLowerCase().contains(libraryName.toLowerCase())) { matchedLibs.add(lib); } } @@ -900,6 +954,12 @@ public class ECTesterStandalone { return false; } else { selected = matchedLibs.get(0); + try { + selected.initialize(); + } catch (Exception ex) { + System.err.println("Error initializing " + selected.fullName()); + System.err.println(ex.getMessage()); + } } } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java index 60c60e8..c0cf793 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java @@ -18,10 +18,11 @@ public class KeyAgreementIdent extends Ident { private static final List<KeyAgreementIdent> ALL = new LinkedList<>(); static { - //https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html + // https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html // Basic ECDH and ECDHC (plain/raw) ALL.add(new KeyAgreementIdent("ECDH")); ALL.add(new KeyAgreementIdent("ECDHC", "ECCDH")); + // ECDH and ECDHC with SHA as KDF, OIDs from RFC 3278 ALL.add(new KeyAgreementIdent("ECDHwithSHA1KDF", true, "1.3.133.16.840.63.0.2")); ALL.add(new KeyAgreementIdent("ECCDHwithSHA1KDF", true, "1.3.133.16.840.63.0.3")); @@ -33,11 +34,13 @@ public class KeyAgreementIdent extends Ident { ALL.add(new KeyAgreementIdent("ECCDHwithSHA384KDF", true, "1.3.132.1.14.2")); ALL.add(new KeyAgreementIdent("ECDHwithSHA512KDF", true, "1.3.132.1.11.3")); ALL.add(new KeyAgreementIdent("ECCDHwithSHA512KDF", true, "1.3.132.1.14.3")); + // Microsoft specific KDF ALL.add(new KeyAgreementIdent("ECDHwithSHA1KDF(CNG)")); ALL.add(new KeyAgreementIdent("ECDHwithSHA256KDF(CNG)")); ALL.add(new KeyAgreementIdent("ECDHwithSHA384KDF(CNG)")); ALL.add(new KeyAgreementIdent("ECDHwithSHA512KDF(CNG)")); + // CKDF requires custom AlgorithmParameterSpec (only BouncyCastle) //ALL.add(new KeyAgreementIdent("ECDHwithSHA1CKDF", true)); //ALL.add(new KeyAgreementIdent("ECCDHwithSHA1CKDF", true)); @@ -47,6 +50,7 @@ public class KeyAgreementIdent extends Ident { //ALL.add(new KeyAgreementIdent("ECCDHwithSHA384CKDF", true)); //ALL.add(new KeyAgreementIdent("ECDHwithSHA512CKDF", true)); //ALL.add(new KeyAgreementIdent("ECCDHwithSHA512CKDF", true)); + // ECMQV - Disable for now as it needs diferent params(too different from DH) //ALL.add(new KeyAgreementIdent("ECMQV")); //ALL.add(new KeyAgreementIdent("ECMQVwithSHA1KDF", true)); @@ -59,10 +63,16 @@ public class KeyAgreementIdent extends Ident { //ALL.add(new KeyAgreementIdent("ECMQVwithSHA256CKDF", true, "1.3.132.1.15.1")); //ALL.add(new KeyAgreementIdent("ECMQVwithSHA384CKDF", true, "1.3.132.1.15.2")); //ALL.add(new KeyAgreementIdent("ECMQVwithSHA512CKDF", true, "1.3.132.1.15.3")); + // ECVKO - Disable for now as it needs diferent params(too different from DH) //ALL.add(new KeyAgreementIdent("ECVKO", "ECGOST3410", "1.2.643.2.2.19", "GOST-3410-2001", "1.2.643.2.2.96")); //ALL.add(new KeyAgreementIdent("ECVKO256", "ECGOST3410-2012-256", "1.2.643.7.1.1.6.1", "1.2.643.7.1.1.1.1")); //ALL.add(new KeyAgreementIdent("ECVKO512", "ECGOST3410-2012-512", "1.2.643.7.1.1.6.2", "1.2.643.7.1.1.1.2")); + + // XDH (RFC 7748) + ALL.add(new KeyAgreementIdent("XDH")); + ALL.add(new KeyAgreementIdent("X25519")); + ALL.add(new KeyAgreementIdent("X448")); } public static KeyAgreementIdent get(String ident) { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java index 83eef75..49b982b 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java @@ -11,6 +11,7 @@ public class KeyPairGeneratorIdent extends Ident { private static final List<KeyPairGeneratorIdent> ALL = new LinkedList<>(); static { + // Short-Weierstrass ALL.add(new KeyPairGeneratorIdent("EC")); ALL.add(new KeyPairGeneratorIdent("ECDH")); ALL.add(new KeyPairGeneratorIdent("ECDSA")); @@ -22,6 +23,14 @@ public class KeyPairGeneratorIdent extends Ident { ALL.add(new KeyPairGeneratorIdent("ECKCDSA")); // ECGDSA? Botan provides. ALL.add(new KeyPairGeneratorIdent("ECGDSA")); + // Montgomery + ALL.add(new KeyPairGeneratorIdent("XDH")); + ALL.add(new KeyPairGeneratorIdent("X25519")); + ALL.add(new KeyPairGeneratorIdent("X448")); + // Twisted-Edwards + ALL.add(new KeyPairGeneratorIdent("EdDSA")); + ALL.add(new KeyPairGeneratorIdent("Ed25519")); + ALL.add(new KeyPairGeneratorIdent("Ed448")); } public static KeyPairGeneratorIdent get(String ident) { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java index c3913b7..a65d0c5 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java @@ -30,17 +30,20 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA3-384withECDSA", "SHA3-384/ECDSA", "2.16.840.1.101.3.4.3.11")); ALL.add(new SignatureIdent("SHA3-512withECDSA", "SHA3-512/ECDSA", "2.16.840.1.101.3.4.3.12")); ALL.add(new SignatureIdent("RIPEMD160withECDSA", "RIPEMD160/ECDSA", "1.3.36.3.3.2.2")); + // ECNR ALL.add(new SignatureIdent("SHA1withECNR")); ALL.add(new SignatureIdent("SHA224withECNR")); ALL.add(new SignatureIdent("SHA256withECNR")); ALL.add(new SignatureIdent("SHA512withECNR")); + // CVC-ECDSA ALL.add(new SignatureIdent("SHA1withCVC-ECDSA", "SHA1/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.1")); ALL.add(new SignatureIdent("SHA224withCVC-ECDSA", "SHA224/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.2")); ALL.add(new SignatureIdent("SHA256withCVC-ECDSA", "SHA256/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.3")); ALL.add(new SignatureIdent("SHA384withCVC-ECDSA", "SHA384/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.4")); ALL.add(new SignatureIdent("SHA512withCVC-ECDSA", "SHA512/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.5")); + // PLAIN-ECDSA ALL.add(new SignatureIdent("SHA1withPLAIN-ECDSA", "SHA1/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.1")); ALL.add(new SignatureIdent("SHA224withPLAIN-ECDSA", "SHA224/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.2")); @@ -48,6 +51,7 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA384withPLAIN-ECDSA", "SHA384/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.4")); ALL.add(new SignatureIdent("SHA512withPLAIN-ECDSA", "SHA512/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.5")); ALL.add(new SignatureIdent("RIPEMD160withPLAIN-ECDSA", "RIPEMD160/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.6")); + // ECGOST ALL.add(new SignatureIdent("ECGOST3410", "ECGOST-3410", "GOST-3410-2001")); ALL.add(new SignatureIdent("GOST3411withECGOST3410", "GOST3411/ECGOST3410", "1.2.643.2.2.3")); @@ -56,6 +60,7 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("ECGOST3410-2012-512", "GOST-3410-2012-512")); ALL.add(new SignatureIdent("GOST3411-2012-512withECGOST3410-2012-512", "GOST3411-2012-512/ECGOST3410-2012-5120", "1.2.643.7.1.1.3.3")); ALL.add(new SignatureIdent("SM3withSM2")); + // ECDDSA (rfc6979?) ALL.add(new SignatureIdent("ECDDSA", "SHA1withECDDSA", "SHA1withDETECDSA", "DETECDSA", "ECDETDSA")); ALL.add(new SignatureIdent("SHA224withECDDSA", "SHA224withDETECDSA")); @@ -66,6 +71,7 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA3-256withECDDSA", "SHA3-256withDETECDSA")); ALL.add(new SignatureIdent("SHA3-384withECDDSA", "SHA3-384withDETECDSA")); ALL.add(new SignatureIdent("SHA3-512withECDDSA", "SHA3-512withDETECDSA")); + // ECKCDSA? Botan provides. ALL.add(new SignatureIdent("ECKCDSA", "SHA1withECKCDSA", "1.2.410.200004.1.100.4.3")); ALL.add(new SignatureIdent("NONEwithECKCDSA")); @@ -74,6 +80,7 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA256withECKCDSA", "1.2.410.200004.1.100.4.5")); ALL.add(new SignatureIdent("SHA384withECKCDSA")); ALL.add(new SignatureIdent("SHA512withECKCDSA")); + // ECGDSA? Botan provides. ALL.add(new SignatureIdent("ECGDSA", "SHA1withECGDSA", "1.3.36.3.3.2.5.4.2")); ALL.add(new SignatureIdent("NONEwithECGDSA")); @@ -82,6 +89,11 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA224withECGDSA", "1.3.36.3.3.2.5.4.4")); ALL.add(new SignatureIdent("SHA384withECGDSA", "1.3.36.3.3.2.5.4.5")); ALL.add(new SignatureIdent("SHA512withECGDSA", "1.3.36.3.3.2.5.4.6")); + + // EdDSA (RFC 8032) + ALL.add(new SignatureIdent("EdDSA")); + ALL.add(new SignatureIdent("Ed25519")); + ALL.add(new SignatureIdent("Ed448")); } public static SignatureIdent get(String ident) { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java index 7f9d96e..c11dbdb 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java @@ -33,7 +33,7 @@ public abstract class NativeECLibrary extends ProviderECLibrary { Path libPath = libDir.resolve(resource + "." + suffix); /* Write the shim. */ - boolean found = FileUtil.writeNewer(ECTesterStandalone.LIB_RESOURCE_DIR + resource + "." + suffix, libPath); + boolean found = FileUtil.write(ECTesterStandalone.LIB_RESOURCE_DIR + resource + "." + suffix, libPath); if (!found) { return false; } @@ -44,7 +44,7 @@ public abstract class NativeECLibrary extends ProviderECLibrary { if (requirement.endsWith(suffix)) { /* The requirement is bundled, write it */ Path reqPath = libReqDir.resolve(requirement); - found = FileUtil.writeNewer(ECTesterStandalone.LIB_RESOURCE_DIR + requirement, reqPath); + found = FileUtil.write(ECTesterStandalone.LIB_RESOURCE_DIR + requirement, reqPath); if (!found) { return false; } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java index 6b60779..d4df414 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java @@ -1,6 +1,15 @@ package cz.crcs.ectester.standalone.libs; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.util.ECUtil; +import cz.crcs.ectester.data.EC_Store; + +import java.security.InvalidAlgorithmParameterException; import java.security.Provider; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.ECParameterSpec; +import java.util.Arrays; import java.util.Set; /** @@ -17,4 +26,27 @@ public class NettleLib extends NativeECLibrary { @Override public native Set<String> getCurves(); + + public static ECGenParameterSpec parametersKnown(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { + if (params instanceof ECGenParameterSpec) { + if (Arrays.asList("secp192r1", "secp224r1", "secp256r1", "secp384r1", "secp521r1").contains(((ECGenParameterSpec) params).getName())) { + return (ECGenParameterSpec) params; + } + } else if (params instanceof ECParameterSpec) { + ECParameterSpec spec = (ECParameterSpec) params; + EC_Store store = EC_Store.getInstance(); + if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp192r1").toSpec())) { + return new ECGenParameterSpec("secp192r1"); + } else if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp224r1").toSpec())) { + return new ECGenParameterSpec("secp224r1"); + } else if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp256r1").toSpec())) { + return new ECGenParameterSpec("secp256r1"); + } else if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp384r1").toSpec())) { + return new ECGenParameterSpec("secp384r1"); + } else if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp521r1").toSpec())) { + return new ECGenParameterSpec("secp521r1"); + } + } + throw new InvalidAlgorithmParameterException("Unknown curve."); + } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java index a9a49e9..d9d6749 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java @@ -104,6 +104,10 @@ public abstract class ProviderECLibrary implements ECLibrary { return name; } + public String fullName() { + return name() + " (" + provider.getName() + ")"; + } + public Provider getProvider() { return provider; } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java index afed02b..d9a4d40 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java @@ -1,6 +1,9 @@ package cz.crcs.ectester.standalone.libs.jni; +import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.common.util.ECUtil; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.standalone.libs.NettleLib; import javax.crypto.KeyAgreementSpi; import javax.crypto.SecretKey; @@ -11,7 +14,6 @@ import java.security.interfaces.ECPublicKey; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; -import java.security.spec.InvalidParameterSpecException; /** * @author Jan Jancar johny@neuromancer.sk @@ -61,6 +63,22 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { return secret.length; } + protected byte[] getPubkey() { + if (publicKey instanceof NativeECPublicKey) { + return ((NativeECPublicKey) publicKey).getData(); + } else { + return ECUtil.pubkeyToBytes(publicKey); + } + } + + protected byte[] getPrivkey() { + if (privateKey instanceof NativeECPrivateKey) { + return ((NativeECPrivateKey) privateKey).getData(); + } else { + return ECUtil.privkeyToBytes(privateKey); + } + } + private abstract static class SimpleKeyAgreementSpi extends NativeKeyAgreementSpi { @Override @@ -72,51 +90,79 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { this.params = params; } - private byte[] getPubkey() { - if (publicKey instanceof NativeECPublicKey) { - return ((NativeECPublicKey) publicKey).getData(); - } else { - return ECUtil.toX962Uncompressed(publicKey.getW(), ((ECParameterSpec) params)); + @Override + protected byte[] engineGenerateSecret() throws IllegalStateException { + return generateSecret(getPubkey(), getPrivkey(), (ECParameterSpec) params); + } + + abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params); + + @Override + protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException { + if (algorithm == null) { + throw new NoSuchAlgorithmException("Algorithm must not be null."); } + return generateSecret(getPubkey(), getPrivkey(), (ECParameterSpec) params, algorithm); } - private byte[] getPrivkey() { - if (privateKey instanceof NativeECPrivateKey) { - return ((NativeECPrivateKey) privateKey).getData(); - } else { - return ECUtil.toByteArray(privateKey.getS(), ((ECParameterSpec) params).getOrder().bitLength()); + abstract SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm); + } + + private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi { + + @Override + protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + if (!(params instanceof ECParameterSpec || params instanceof ECGenParameterSpec)) { + throw new InvalidAlgorithmParameterException("Unknown parameter class."); } + engineInit(key, random); + this.params = params; } @Override protected byte[] engineGenerateSecret() throws IllegalStateException { - return generateSecret(getPubkey(), getPrivkey(), (ECParameterSpec) params); + return generateSecret(publicKey, privateKey, params); } - abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params); + abstract byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params); @Override protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException { if (algorithm == null) { throw new NoSuchAlgorithmException("Algorithm must not be null"); } - return generateSecret(getPubkey(), getPrivkey(), (ECParameterSpec) params, algorithm); + return generateSecret(publicKey, privateKey, params, algorithm); } - abstract SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm); + abstract SecretKey generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params, String algorithm); } - private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi { + private abstract static class NamedKeyAgreementSpi extends NativeKeyAgreementSpi { + + @Override + protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException { + if (!(key instanceof ECPrivateKey)) { + throw new InvalidKeyException("Key must be instance of ECPrivateKey"); + } + privateKey = (ECPrivateKey) key; + try { + this.params = parametersKnown(privateKey.getParams()); + } catch (InvalidAlgorithmParameterException e) { + throw new InvalidKeyException(e); + } + } @Override protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { if (!(params instanceof ECParameterSpec || params instanceof ECGenParameterSpec)) { - throw new InvalidAlgorithmParameterException(); + throw new InvalidAlgorithmParameterException("Unknown parameter class."); } engineInit(key, random); - this.params = params; + this.params = parametersKnown(params); } + abstract ECGenParameterSpec parametersKnown(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException; + @Override protected byte[] engineGenerateSecret() throws IllegalStateException { return generateSecret(publicKey, privateKey, params); @@ -374,7 +420,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { } } - public abstract static class Nettle extends SimpleKeyAgreementSpi { + public abstract static class Nettle extends NamedKeyAgreementSpi { private final String type; public Nettle(String type) { @@ -382,43 +428,21 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { } @Override - byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params) { - try { - // TODO: OMG remove this monstrosity. - AlgorithmParameters tmp = AlgorithmParameters.getInstance("EC"); - tmp.init(params); - ECGenParameterSpec spec = tmp.getParameterSpec(ECGenParameterSpec.class); - switch (spec.getName()) { - case "1.2.840.10045.3.1.7": - spec = new ECGenParameterSpec("secp256r1"); - break; - case "1.2.840.10045.3.1.1": - spec = new ECGenParameterSpec("secp192r1"); - break; - case "1.3.132.0.33": - spec = new ECGenParameterSpec("secp224r1"); - break; - case "1.3.132.0.34": - spec = new ECGenParameterSpec("secp384r1"); - break; - case "1.3.132.0.35": - spec = new ECGenParameterSpec("secp521r1"); - break; - default: - return null; + ECGenParameterSpec parametersKnown(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { + return NettleLib.parametersKnown(params); + } - } - return generateSecret(pubkey, privkey, spec); + @Override + byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params) { + return generateSecret(getPubkey(), getPrivkey(), (ECGenParameterSpec) params); + } - } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) { - return null; - } + @Override + SecretKey generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params, String algorithm) { + throw new UnsupportedOperationException("Not supported."); } native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECGenParameterSpec params); - - @Override - native SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm); } public static class NettleECDH extends Nettle { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java index 0a9487f..086c2c4 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.standalone.libs.jni; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.standalone.libs.NettleLib; import java.security.*; import java.security.spec.AlgorithmParameterSpec; @@ -293,7 +294,7 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi { @Override native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random); } - + public static class Libressl extends NativeKeyPairGeneratorSpi { public Libressl() { @@ -319,26 +320,48 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi { } @Override - native boolean keysizeSupported(int keysize); + boolean keysizeSupported(int keysize) { + switch (keysize) { + case 192, 224, 256, 384, 521: + return true; + default: + return false; + } + } @Override - native boolean paramsSupported(AlgorithmParameterSpec params); + boolean paramsSupported(AlgorithmParameterSpec params) { + try { + NettleLib.parametersKnown(params); + return true; + } catch (InvalidAlgorithmParameterException ignored) { + return false; + } + } @Override - native KeyPair generate(int keysize, SecureRandom random); + KeyPair generate(int keysize, SecureRandom random) { + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, "secg/secp" + keysize + "r1"); + return generate(keysize, random, curve.toSpec()); + } + + native KeyPair generate(int keysize, SecureRandom random, AlgorithmParameterSpec spec); @Override KeyPair generate(AlgorithmParameterSpec params, SecureRandom random) { - if (params instanceof ECGenParameterSpec) { - String curveName = ((ECGenParameterSpec) params).getName(); - if (curveName.contains("secp")) { - curveName = "secg/" + curveName; - } - EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); - ECParameterSpec spec = curve.toSpec(); - return generate(params, random, spec); + ECGenParameterSpec named; + try { + named = NettleLib.parametersKnown(params); + } catch (InvalidAlgorithmParameterException ignored) { + return null; + } + String curveName = named.getName(); + if (curveName.startsWith("secp")) { + curveName = "secg/" + curveName; } - return null; + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); + ECParameterSpec spec = curve.toSpec(); + return generate(params, random, spec); } native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random, AlgorithmParameterSpec spec); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SigInfo.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SigInfo.java new file mode 100644 index 0000000..3cb7bad --- /dev/null +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SigInfo.java @@ -0,0 +1,80 @@ +package cz.crcs.ectester.standalone.libs.jni; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class SigInfo { + + private final int signo; + private final int code; + private final int errno; + private final int pid; + private final int uid; + private final long addr; + private final int status; + private final long band; + private final long sigval; + + public SigInfo(int signo, int code, int errno, int pid, int uid, long addr, int status, long band, long sigval) { + this.signo = signo; + this.code = code; + this.errno = errno; + this.pid = pid; + this.uid = uid; + this.addr = addr; + this.status = status; + this.band = band; + this.sigval = sigval; + } + + public int getSigno() { + return signo; + } + + public int getCode() { + return code; + } + + public int getErrno() { + return errno; + } + + public int getPid() { + return pid; + } + + public int getUid() { + return uid; + } + + public long getAddr() { + return addr; + } + + public int getStatus() { + return status; + } + + public long getBand() { + return band; + } + + public long getSigval() { + return sigval; + } + + @Override + public String toString() { + return "SigInfo{" + + "signo=" + signo + + ", code=" + code + + ", errno=" + errno + + ", pid=" + pid + + ", uid=" + uid + + ", addr=" + addr + + ", status=" + status + + ", band=" + band + + ", sigval=" + sigval + + '}'; + } +} diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SignalException.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SignalException.java new file mode 100644 index 0000000..726286e --- /dev/null +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SignalException.java @@ -0,0 +1,18 @@ +package cz.crcs.ectester.standalone.libs.jni; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class SignalException extends RuntimeException { + + private final SigInfo sigInfo; + + public SignalException(SigInfo sigInfo) { + super("Signal caught."); + this.sigInfo = sigInfo; + } + + public SigInfo getSigInfo() { + return sigInfo; + } +} diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/TimeoutException.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/TimeoutException.java new file mode 100644 index 0000000..c4084b9 --- /dev/null +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/TimeoutException.java @@ -0,0 +1,11 @@ +package cz.crcs.ectester.standalone.libs.jni; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TimeoutException extends RuntimeException { + + public TimeoutException(String message) { + super(message); + } +} diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java b/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java index ba345e7..c53adb2 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java @@ -48,7 +48,7 @@ public class TextTestWriter extends BaseTextTestWriter { StandaloneTestSuite standaloneSuite = (StandaloneTestSuite) suite; StringBuilder sb = new StringBuilder(); sb.append("═══ ").append(Colors.underline("ECTester version:")).append(" ").append(ECTesterStandalone.VERSION).append(System.lineSeparator()); - sb.append("═══ ").append(Colors.underline("Library:")).append(" ").append(standaloneSuite.getLibrary().name()).append(System.lineSeparator()); + sb.append("═══ ").append(Colors.underline("Library:")).append(" ").append(standaloneSuite.getLibrary().fullName()).append(System.lineSeparator()); return sb.toString(); } return ""; diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java b/standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java index 60751f5..2341fc7 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java @@ -147,7 +147,7 @@ public class XMLTestWriter extends BaseXMLTestWriter { result.setAttribute("ectester", ECTesterStandalone.VERSION); Element name = doc.createElement("name"); - name.setTextContent(standaloneSuite.getLibrary().name()); + name.setTextContent(standaloneSuite.getLibrary().fullName()); result.appendChild(name); return result; } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java b/standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java index 664fa18..66c5e38 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java @@ -116,7 +116,7 @@ public class YAMLTestWriter extends BaseYAMLTestWriter { Map<String, Object> result = new LinkedHashMap<>(); result.put("type", "library"); result.put("ectester", ECTesterStandalone.VERSION); - result.put("name", standaloneSuite.getLibrary().name()); + result.put("name", standaloneSuite.getLibrary().fullName()); return result; } return null; diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java index 32f82cb..8c49224 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java @@ -4,6 +4,9 @@ import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.SimpleTest; import cz.crcs.ectester.common.test.TestCallback; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.ECParameterSpec; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -38,6 +41,15 @@ public class KeyGeneratorTest extends SimpleTest<KeyGeneratorTestable> { @Override public String getDescription() { - return "KeyPairGenerator " + testable.getKpg().getAlgorithm(); + String params = ""; + if (testable.getKeysize() != 0) { + params = String.format("(default %d-bit curve)", testable.getKeysize()); + } else if (testable.getSpec() instanceof ECGenParameterSpec) { + String name = ((ECGenParameterSpec)testable.getSpec()).getName(); + params = String.format("(%s)", name); + } else if (testable.getSpec() instanceof ECParameterSpec) { + params = "(custom curve)"; + } + return "KeyPairGenerator " + testable.getKpg().getAlgorithm() + " on " + params; } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java index 296ec3c..bc44eb8 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java @@ -3,6 +3,8 @@ package cz.crcs.ectester.standalone.test.base; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; /** @@ -12,7 +14,7 @@ public class KeyGeneratorTestable extends StandaloneTestable<KeyGeneratorTestabl private KeyPair kp; private final KeyPairGenerator kpg; private int keysize = 0; - private ECParameterSpec spec = null; + private AlgorithmParameterSpec spec = null; public KeyGeneratorTestable(KeyPairGenerator kpg) { this.kpg = kpg; @@ -28,6 +30,19 @@ public class KeyGeneratorTestable extends StandaloneTestable<KeyGeneratorTestabl this.spec = spec; } + public KeyGeneratorTestable(KeyPairGenerator kpg, ECGenParameterSpec spec) { + this.kpg = kpg; + this.spec = spec; + } + + public int getKeysize() { + return keysize; + } + + public AlgorithmParameterSpec getSpec() { + return spec; + } + public KeyPairGenerator getKpg() { return kpg; } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java index 52b0fbf..bb9a509 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java @@ -76,10 +76,10 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite { ECParameterSpec spec = curve.toSpec(); KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); runTest(generate); KeyPair kp = kgt.getKeyPair(); - if(kp == null) { + if (kp == null) { Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId() + ".", generateFail)); continue; @@ -101,7 +101,7 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with public points on non-generator subgroup.", specificKaTests.toArray(new Test[0]))); } } - if(allKaTests.isEmpty()) { + if (allKaTests.isEmpty()) { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java index c59d864..839bb40 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java @@ -85,10 +85,10 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { //Generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); runTest(generate); KeyPair kp = kgt.getKeyPair(); - if(kp == null) { + if (kp == null) { Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", generateFail)); continue; @@ -104,14 +104,14 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { for (EC_Key.Public pub : curveKeys.getValue()) { ECPublicKey ecpub = ECUtil.toPublicKey(pub); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv ,ecpub); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with generated private key, " + pub.getDesc(), keyAgreement)); } allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with various public points.", specificKaTests.toArray(new Test[0]))); } } - if(allKaTests.isEmpty()) { + if (allKaTests.isEmpty()) { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); @@ -153,7 +153,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { } private void testGroup(List<EC_Curve> curves, KeyPairGenerator kpg, String testName, Result.ExpectedValue dhValue) throws Exception { - for (EC_Curve curve : curves) { + for (EC_Curve curve : curves) { String description; if (testName == null) { description = curve.getDesc() + " test of " + curve.getId() + "."; @@ -162,19 +162,19 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { } //generate KeyPair - KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, curve.toSpec()); - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if(kp == null) { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + - ". " + " Other tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, description, generateFail)); - continue; - } - Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); - ECPublicKey ecpub = (ECPublicKey) kp.getPublic(); + KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, curve.toSpec()); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); + runTest(generate); + KeyPair kp = kgt.getKeyPair(); + if (kp == null) { + Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + + ". " + " Other tests will be skipped.", generate); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, description, generateFail)); + continue; + } + Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); + ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); + ECPublicKey ecpub = (ECPublicKey) kp.getPublic(); //perform KeyAgreement tests List<Test> kaTests = new LinkedList<>(); @@ -185,7 +185,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { kaTests.add(KeyAgreementTest.expectError(testable, dhValue)); } } - if(kaTests.isEmpty()) { + if (kaTests.isEmpty()) { kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified KeyAgreement types is supported by the library.")); } @@ -198,7 +198,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { sigTests.add(SignatureTest.expectError(testable, dhValue)); } } - if(sigTests.isEmpty()) { + if (sigTests.isEmpty()) { sigTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified Signature types is supported by the library.")); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java index 9ab8a39..d822a83 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java @@ -22,6 +22,7 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; +import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.util.*; @@ -77,22 +78,34 @@ public class StandaloneDegenerateSuite extends StandaloneTestSuite { KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); Test generateSuccess; - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); runTest(generate); KeyPair kp = kgt.getKeyPair(); - if(kp != null) { + if (kp != null) { generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { //If KeyPair generation fails, try generating it on a default curve instead. Use this key only if it has the same domain parameters as our public key. - KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); - Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); - runTest(generateOnDefaultCurve); - kp = kgtOnDefaultCurve.getKeyPair(); - if(kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve); + } else { + // If KeyPair generation fails, try generating it on named curve instead. + ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); + KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); + Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY); + runTest(generateOnNamedCurve); + kp = kgtOnNamedCurve.getKeyPair(); + if (kp != null) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve); } else { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", generateFail)); - continue; + // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key. + KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); + Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); + runTest(generateOnDefaultCurve); + kp = kgtOnDefaultCurve.getKeyPair(); + if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve); + } else { + Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve); + Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", generateFail)); + continue; + } } } ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); @@ -111,7 +124,7 @@ public class StandaloneDegenerateSuite extends StandaloneTestSuite { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with degenerate public points..", specificKaTests.toArray(new Test[0]))); } } - if(allKaTests.isEmpty()) { + if (allKaTests.isEmpty()) { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java index 1900bea..7c46f02 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java @@ -264,10 +264,10 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { //generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); runTest(generate); KeyPair kp = kgt.getKeyPair(); - if(kp == null) { + if (kp == null) { Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + secp160r1.getBits() + "b secp160r1." + " Other tests will be skipped.", generate); doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test private key values near zero, near p and near/larger than the order on" + secp160r1.getId() + ".", generateFail)); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java index ace8945..48dfc37 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java @@ -22,6 +22,7 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; +import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.util.*; @@ -76,22 +77,34 @@ public class StandaloneInvalidSuite extends StandaloneTestSuite { KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); Test generateSuccess; - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); runTest(generate); KeyPair kp = kgt.getKeyPair(); - if(kp != null) { + if (kp != null) { generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { //If KeyPair generation fails, try generating it on a default curve instead. Use this key only if it has the same domain parameters as our public key. - KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); - Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); - runTest(generateOnDefaultCurve); - kp = kgtOnDefaultCurve.getKeyPair(); - if(kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve); + } else { + // If KeyPair generation fails, try generating it on named curve instead. + ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); + KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); + Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY); + runTest(generateOnNamedCurve); + kp = kgtOnNamedCurve.getKeyPair(); + if (kp != null) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve); } else { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", generateFail)); - continue; + // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key. + KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); + Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); + runTest(generateOnDefaultCurve); + kp = kgtOnDefaultCurve.getKeyPair(); + if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve); + } else { + Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve); + Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", generateFail)); + continue; + } } } ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); @@ -110,7 +123,7 @@ public class StandaloneInvalidSuite extends StandaloneTestSuite { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with invalid public points.", specificKaTests.toArray(new Test[0]))); } } - if(allKaTests.isEmpty()) { + if (allKaTests.isEmpty()) { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java index e3b6d2e..a1b4d75 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java @@ -73,7 +73,7 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { KeyGeneratorTestable kgtOther = null; ECParameterSpec spec = null; List<Test> kpgTests = new LinkedList<>(); - for(KeyPairGeneratorIdent kpgIdent : kpgIdents) { + for (KeyPairGeneratorIdent kpgIdent : kpgIdents) { KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); if (cli.hasOption("test.bits")) { int bits = Integer.parseInt(cli.getOptionValue("test.bits")); @@ -111,7 +111,7 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { kaTests.add(PerformanceTest.repeat(testable, cfg.selected, kaIdent.getName(), count)); } } - if(kaTests.isEmpty()) { + if (kaTests.isEmpty()) { kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified KeyAgreement types is supported by the library.")); } doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement performance tests", kaTests.toArray(new Test[0]))); @@ -121,17 +121,17 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { for (SignatureIdent sigIdent : cfg.selected.getSigs()) { if (sigAlgo == null || sigIdent.containsAny(sigTypes)) { Signature sig = sigIdent.getInstance(cfg.selected.getProvider()); - sigTests.add(PerformanceTest.repeat(new SignatureTestable(sig, kgtOne, null), cfg.selected, sigIdent.getName(),count)); - if(kgtOne.getKeyPair() != null) { + sigTests.add(PerformanceTest.repeat(new SignatureTestable(sig, kgtOne, null), cfg.selected, sigIdent.getName(), count)); + if (kgtOne.getKeyPair() != null) { ECPrivateKey signKey = (ECPrivateKey) kgtOne.getKeyPair().getPrivate(); sigTestsNoVerification.add(PerformanceTest.repeat(new SignatureTestable(sig, signKey, null, null), cfg.selected, sigIdent.getName(), count)); } } } - if(sigTestsNoVerification.isEmpty() & !sigTests.isEmpty()) { + if (sigTestsNoVerification.isEmpty() & !sigTests.isEmpty()) { sigTestsNoVerification.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Signature tests with no verification require a successfully generated private key.")); } - if(sigTests.isEmpty()) { + if (sigTests.isEmpty()) { sigTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified Signature types is supported by the library.")); sigTestsNoVerification.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified Signature types is supported by the library.")); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java index 94e810e..8e5e452 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java @@ -73,6 +73,10 @@ public class StandaloneSignatureSuite extends StandaloneTestSuite { } private void ecdsaTest(EC_SigResult sig, SignatureIdent sigIdent, Result.ExpectedValue expected, byte[] defaultData) throws NoSuchAlgorithmException { + if (!sig.getSig().equals(sigIdent.getHashAlgo()) && !sig.getSig().equals("*")) { + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "ECDSA test of " + sig.getId() + " not applicable.")); + return; + } ECPublicKey ecpub = ECUtil.toPublicKey(EC_Store.getInstance().getObject(EC_Key.Public.class, sig.getVerifyKey())); byte[] data = sig.getSigData(); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java index 1e1889c..111d354 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java @@ -31,7 +31,7 @@ public class StandaloneTestVectorSuite extends StandaloneTestSuite { protected void runTests() throws Exception { Map<String, EC_KAResult> results = EC_Store.getInstance().getObjects(EC_KAResult.class, "test"); for (EC_KAResult result : results.values()) { - if(!"DH_PLAIN".equals(result.getKA())) { + if (!"DH_PLAIN".equals(result.getKA())) { continue; } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java index f182952..37adbb2 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java @@ -22,6 +22,7 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; +import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.util.*; @@ -76,22 +77,34 @@ public class StandaloneTwistSuite extends StandaloneTestSuite { KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); Test generateSuccess; - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); runTest(generate); KeyPair kp = kgt.getKeyPair(); - if(kp != null) { + if (kp != null) { generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { //If KeyPair generation fails, try generating it on a default curve instead. Use this key only if it has the same domain parameters as our public key. - KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); - Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); - runTest(generateOnDefaultCurve); - kp = kgtOnDefaultCurve.getKeyPair(); - if(kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve); + } else { + // If KeyPair generation fails, try generating it on named curve instead. + ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); + KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); + Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY); + runTest(generateOnNamedCurve); + kp = kgtOnNamedCurve.getKeyPair(); + if (kp != null) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve); } else { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", generateFail)); - continue; + // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key. + KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); + Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); + runTest(generateOnDefaultCurve); + kp = kgtOnDefaultCurve.getKeyPair(); + if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve); + } else { + Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve); + Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", generateFail)); + continue; + } } } ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); @@ -110,7 +123,7 @@ public class StandaloneTwistSuite extends StandaloneTestSuite { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with public points on twist.", specificKaTests.toArray(new Test[0]))); } } - if(allKaTests.isEmpty()) { + if (allKaTests.isEmpty()) { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java index a457a33..1aae9d5 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java @@ -103,7 +103,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { /* Just do the default run on the wrong curves. * These should generally fail, the curves aren't curves. */ - if(!skip) { + if (!skip) { Map<String, EC_Curve> wrongCurves = EC_Store.getInstance().getObjects(EC_Curve.class, "wrong"); for (Map.Entry<String, EC_Curve> e : wrongCurves.entrySet()) { @@ -151,11 +151,11 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { short bits = curve.getBits(); final byte[] originalp = curve.getParam(EC_Consts.PARAMETER_FP)[0]; - curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{ ByteUtil.hexToBytes("0")}); - Test prime0 = ecdhTest(toCustomSpec(curve),"ECDH with p = 0."); + curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{ByteUtil.hexToBytes("0")}); + Test prime0 = ecdhTest(toCustomSpec(curve), "ECDH with p = 0."); - curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{ ByteUtil.hexToBytes("1")}); - Test prime1 = ecdhTest(toCustomSpec(curve),"ECDH with p = 1."); + curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{ByteUtil.hexToBytes("1")}); + Test prime1 = ecdhTest(toCustomSpec(curve), "ECDH with p = 1."); short keyHalf = (short) (bits / 2); BigInteger prime = new BigInteger(keyHalf, 50, r); @@ -173,23 +173,23 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { Test composite = ecdhTest(toCustomSpec(curve), "ECDH with p = q * s."); - Test wrongPrime = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted prime parameter.", prime0 , prime1, primePower, composite ); + Test wrongPrime = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted prime parameter.", prime0, prime1, primePower, composite); - curve.setParam(EC_Consts.PARAMETER_FP, new byte[][] {originalp}); + curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{originalp}); final byte[][] originalG = curve.getParam(EC_Consts.PARAMETER_G); byte[] Gx = new BigInteger(curve.getBits(), r).toByteArray(); byte[] Gy = new BigInteger(curve.getBits(), r).toByteArray(); - curve.setParam(EC_Consts.PARAMETER_G, new byte[][] {Gx, Gy}); + curve.setParam(EC_Consts.PARAMETER_G, new byte[][]{Gx, Gy}); Test fullRandomG = ecdhTest(toCustomSpec(curve), "ECDH with G = random data."); final BigInteger originalBigp = new BigInteger(1, originalp); byte[] smallerGx = new BigInteger(curve.getBits(), r).mod(originalBigp).toByteArray(); byte[] smallerGy = new BigInteger(curve.getBits(), r).mod(originalBigp).toByteArray(); - curve.setParam(EC_Consts.PARAMETER_G, new byte[][] {smallerGx, smallerGy}); + curve.setParam(EC_Consts.PARAMETER_G, new byte[][]{smallerGx, smallerGy}); Test randomG = ecdhTest(toCustomSpec(curve), "ECDH with G = random data mod p."); - curve.setParam(EC_Consts.PARAMETER_G, new byte[][] {ByteUtil.hexToBytes("0"), ByteUtil.hexToBytes("0")}); + curve.setParam(EC_Consts.PARAMETER_G, new byte[][]{ByteUtil.hexToBytes("0"), ByteUtil.hexToBytes("0")}); Test zeroG = ecdhTest(toCustomSpec(curve), "ECDH with G = infinity."); Test wrongG = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted G parameter.", fullRandomG, randomG, zeroG); @@ -199,7 +199,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { final BigInteger originalBigR = new BigInteger(1, originalR); List<Test> allRTests = new LinkedList<>(); - if(!skip) { + if (!skip) { byte[] RZero = new byte[]{(byte) 0}; curve.setParam(EC_Consts.PARAMETER_R, new byte[][]{RZero}); allRTests.add(ecdhTest(toCustomSpec(curve), "ECDH with R = 0.")); @@ -215,7 +215,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { prevPrimeR = BigInteger.probablePrime(originalBigR.bitLength() - 1, r); } while (prevPrimeR.compareTo(originalBigR) >= 0); byte[] prevRBytes = ECUtil.toByteArray(prevPrimeR, bits); - curve.setParam(EC_Consts.PARAMETER_R, new byte[][] {prevRBytes}); + curve.setParam(EC_Consts.PARAMETER_R, new byte[][]{prevRBytes}); allRTests.add(ecdhTest(toCustomSpec(curve), "ECDH with R = some prime (but [r]G != infinity) smaller than original R.")); BigInteger nextPrimeR = originalBigR.nextProbablePrime(); @@ -225,15 +225,15 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { byte[] nonprimeRBytes = nextRBytes.clone(); nonprimeRBytes[nonprimeRBytes.length - 1] ^= 1; - curve.setParam(EC_Consts.PARAMETER_R, new byte[][] {nonprimeRBytes} ); + curve.setParam(EC_Consts.PARAMETER_R, new byte[][]{nonprimeRBytes}); allRTests.add(ecdhTest(toCustomSpec(curve), "ECDH with R = some composite (but [r]G != infinity).")); Test wrongR = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted R parameter.", allRTests.toArray(new Test[0])); - curve.setParam(EC_Consts.PARAMETER_R, new byte[][] {originalR}); + curve.setParam(EC_Consts.PARAMETER_R, new byte[][]{originalR}); byte[] kRaw = new byte[]{(byte) 0xff}; - curve.setParam(EC_Consts.PARAMETER_K, new byte[][] {kRaw}); + curve.setParam(EC_Consts.PARAMETER_K, new byte[][]{kRaw}); Test bigK = ecdhTest(toCustomSpec(curve), "ECDH with big K."); byte[] kZero = new byte[]{(byte) 0}; @@ -241,7 +241,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { Test zeroK = ecdhTest(toCustomSpec(curve), "ECDH with K = 0."); Test wrongK = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted K parameter.", bigK, zeroK); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of " + bits + "b " + "FP", wrongPrime, wrongG, wrongR , wrongK)); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of " + bits + "b " + "FP", wrongPrime, wrongG, wrongR, wrongK)); } @@ -284,10 +284,10 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { private Test ecdhTest(ECParameterSpec spec, String desc) throws NoSuchAlgorithmException { //generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.FAILURE); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.FAILURE); runTest(generate); KeyPair kp = kgt.getKeyPair(); - if(kp == null) { + if (kp == null) { return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, generate); } ECPublicKey pub = (ECPublicKey) kp.getPublic(); |
