diff options
Diffstat (limited to 'src')
14 files changed, 604 insertions, 115 deletions
diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index a8e4ce9..ad35012 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -43,12 +43,12 @@ public class TextTestWriter extends BaseTextTestWriter { if (suite instanceof CardTestSuite) { CardTestSuite cardSuite = (CardTestSuite) suite; StringBuilder sb = new StringBuilder(); - sb.append("═══ " + Colors.underline("ECTester version:") + " " + ECTesterReader.VERSION + ECTesterReader.GIT_COMMIT).append(System.lineSeparator()); - sb.append("═══ " + Colors.underline("Card ATR:") + " ").append(ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)).append(System.lineSeparator()); + sb.append("═══ ").append(Colors.underline("ECTester version:")).append(" ").append(ECTesterReader.VERSION).append(ECTesterReader.GIT_COMMIT).append(System.lineSeparator()); + sb.append("═══ ").append(Colors.underline("Card ATR:")).append(" ").append(ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)).append(System.lineSeparator()); try { CardMngr.CPLC cplc = cardSuite.getCard().getCPLC(); if (!cplc.values().isEmpty()) { - sb.append("═══ " + Colors.underline("Card CPLC data:")).append(System.lineSeparator()); + sb.append("═══ ").append(Colors.underline("Card CPLC data:")).append(System.lineSeparator()); for (Map.Entry<CardMngr.CPLC.Field, byte[]> entry : cplc.values().entrySet()) { CardMngr.CPLC.Field field = entry.getKey(); byte[] value = entry.getValue(); diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index c223af6..9df6c61 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -66,7 +66,7 @@ import java.util.stream.Collectors; * @version v0.2.0 */ public class ECTesterStandalone { - private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib(), new CryptoppLib()}; + private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib(), new CryptoppLib(), new OpensslLib()}; private Config cfg; private Options opts = new Options(); @@ -205,6 +205,7 @@ public class ECTesterStandalone { opts.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build()); opts.addOption(Option.builder("h").longOpt("help").desc("Print help.").build()); + opts.addOption(Option.builder("C").longOpt("color").desc("Print stuff with color, requires ANSI terminal.").build()); return optParser.parse(opts, args); } @@ -215,22 +216,22 @@ public class ECTesterStandalone { private void listLibraries() { for (ProviderECLibrary lib : libs) { if (lib.isInitialized() && (cfg.selected == null || lib == cfg.selected)) { - System.out.println("\t- " + lib.name()); + System.out.println("\t- " + Colors.bold(lib.name())); Set<KeyPairGeneratorIdent> kpgs = lib.getKPGs(); if (!kpgs.isEmpty()) { - System.out.println("\t\t- KeyPairGenerators: " + String.join(", ", kpgs.stream().map(KeyPairGeneratorIdent::getName).collect(Collectors.toList()))); + System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + String.join(", ", kpgs.stream().map(KeyPairGeneratorIdent::getName).collect(Collectors.toList()))); } Set<KeyAgreementIdent> eckas = lib.getKAs(); if (!eckas.isEmpty()) { - System.out.println("\t\t- KeyAgreements: " + String.join(", ", eckas.stream().map(KeyAgreementIdent::getName).collect(Collectors.toList()))); + System.out.println(Colors.bold("\t\t- KeyAgreements: ") + String.join(", ", eckas.stream().map(KeyAgreementIdent::getName).collect(Collectors.toList()))); } Set<SignatureIdent> sigs = lib.getSigs(); if (!sigs.isEmpty()) { - System.out.println("\t\t- Signatures: " + String.join(", ", sigs.stream().map(SignatureIdent::getName).collect(Collectors.toList()))); + System.out.println(Colors.bold("\t\t- Signatures: ") + String.join(", ", sigs.stream().map(SignatureIdent::getName).collect(Collectors.toList()))); } Set<String> curves = lib.getCurves(); if (!curves.isEmpty()) { - System.out.println("\t\t- Curves: " + String.join(", ", curves)); + System.out.println(Colors.bold("\t\t- Curves: ") + String.join(", ", curves)); } System.out.println(); } @@ -540,12 +541,16 @@ public class ECTesterStandalone { public static class Config { private ProviderECLibrary[] libs; public ProviderECLibrary selected = null; + public boolean color = false; public Config(ProviderECLibrary[] libs) { this.libs = libs; } boolean readOptions(TreeCommandLine cli) { + color = cli.hasOption("color"); + Colors.enabled = color; + if (cli.isNext("generate") || cli.isNext("export") || cli.isNext("ecdh") || cli.isNext("ecdsa") || cli.isNext("test")) { if (!cli.hasArg(-1)) { System.err.println("Missing library name argument."); diff --git a/src/cz/crcs/ectester/standalone/libs/OpensslLib.java b/src/cz/crcs/ectester/standalone/libs/OpensslLib.java new file mode 100644 index 0000000..e558336 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/libs/OpensslLib.java @@ -0,0 +1,19 @@ +package cz.crcs.ectester.standalone.libs; + +import java.security.Provider; +import java.util.Set; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class OpensslLib extends NativeECLibrary { + public OpensslLib() { + super("openssl_provider", "crypto"); + } + + @Override + native Provider createProvider(); + + @Override + public native Set<String> getCurves(); +} diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile b/src/cz/crcs/ectester/standalone/libs/jni/Makefile index 17c1efb..9c3557c 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile +++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile @@ -42,7 +42,7 @@ CFLAGS+=-fPIC -g -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I. CXXFLAGS+=-fPIC -g -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I. -all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so +all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so # Common utils c_utils.o: c_utils.c @@ -52,6 +52,14 @@ cpp_utils.o: cpp_utils.cpp $(CXX) $(CXXFLAGS) -c $< +# OpenSSL shim +openssl_provider.so: openssl.o c_utils.o + $(CC) -fPIC -g -shared -o $@ $^ -L. $(shell pkg-config --libs openssl) + +openssl.o: openssl.c + $(CC) $(shel pkg-config --cflags openssl) $(CFLAGS) -c $< + + # Libtomcrypt shim tomcrypt_provider.so: tomcrypt.o c_utils.o $(CC) -fPIC -g -shared -o $@ $^ -L. -ltommath $(shell pkg-config --libs libtomcrypt) diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java index a209fa1..39539df 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java @@ -71,4 +71,10 @@ public abstract class NativeECPrivateKey implements ECPrivateKey { super(keyData, params); } } + + public static class Openssl extends Raw { + public Openssl(byte[] keyData, ECParameterSpec params) { + super(keyData, params); + } + } } diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java index f53cd26..1085083 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java @@ -73,4 +73,10 @@ public abstract class NativeECPublicKey implements ECPublicKey { super(keyData, params); } } + + public static class Openssl extends ANSIX962 { + public Openssl(byte[] keyData, ECParameterSpec params) { + super(keyData, params); + } + } } diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java index a7b1a61..6e441e5 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java @@ -155,4 +155,22 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi { super("ECDSA"); } } + + public static class Openssl extends NativeKeyPairGeneratorSpi { + public Openssl() { + initialize(256, new SecureRandom()); + } + + @Override + native boolean keysizeSupported(int keysize); + + @Override + native boolean paramsSupported(AlgorithmParameterSpec params); + + @Override + native KeyPair generate(int keysize, SecureRandom random); + + @Override + native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random); + } } diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java index 593295e..a4967e5 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java @@ -49,4 +49,14 @@ public abstract class NativeProvider extends Provider { @Override native void setup(); } + + public static class Openssl extends NativeProvider { + + public Openssl(String name, double version, String info) { + super(name, version, info); + } + + @Override + native void setup(); + } } diff --git a/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp b/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp index 6a1e6d6..a37cb88 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp +++ b/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp @@ -20,11 +20,6 @@ static jclass provider_class; -/* - * Class: cz_crcs_ectester_standalone_libs_BotanLib - * Method: createProvider - * Signature: ()Ljava/security/Provider; - */ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_createProvider(JNIEnv *env, jobject self) { /* Create the custom provider. */ jclass local_provider_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeProvider$Botan"); @@ -44,11 +39,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_createP return env->NewObject(provider_class, init, name, version, info); } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan - * Method: setup - * Signature: ()V - */ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Botan_setup(JNIEnv *env, jobject self){ jmethodID provider_put = env->GetMethodID(provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); @@ -88,11 +78,6 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_ init_classes(env, "Botan"); } -/* - * Class: cz_crcs_ectester_standalone_libs_BotanLib - * Method: getCurves - * Signature: ()Ljava/util/Set; - */ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurves(JNIEnv *env, jobject self){ jclass set_class = env->FindClass("java/util/TreeSet"); @@ -111,20 +96,10 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurv return result; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan - * Method: keysizeSupported - * Signature: (I)Z - */ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_keysizeSupported(JNIEnv *env, jobject self, jint keysize){ return JNI_TRUE; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan - * Method: paramsSupported - * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z - */ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_paramsSupported(JNIEnv *env, jobject self, jobject params){ if (params == NULL) { return JNI_FALSE; @@ -319,11 +294,6 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr return env->NewObject(keypair_class, keypair_init, pubkey, privkey); } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan - * Method: generate - * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair; - */ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random){ const std::set<std::string>& curves = Botan::EC_Group::known_named_groups(); for (auto it = curves.begin(); it != curves.end(); ++it) { @@ -339,21 +309,11 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai return NULL; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan - * Method: generate - * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair; - */ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){ Botan::EC_Group curve_group = group_from_params(env, params); return generate_from_group(env, self, curve_group); } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Botan - * Method: generateSecret - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B - */ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Botan_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params){ Botan::EC_Group curve_group = group_from_params(env, params); @@ -420,11 +380,6 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey return result; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan - * Method: sign - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B - */ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Botan_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params){ Botan::EC_Group curve_group = group_from_params(env, params); @@ -488,11 +443,6 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig return result; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan - * Method: verify - * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z - */ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Botan_verify(JNIEnv *env, jobject self, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params){ Botan::EC_Group curve_group = group_from_params(env, params); diff --git a/src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp b/src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp index e83f808..0ba026f 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp +++ b/src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp @@ -70,11 +70,6 @@ using CryptoPP::Integer; static jclass provider_class; -/* - * Class: cz_crcs_ectester_standalone_libs_CryptoppLib - * Method: createProvider - * Signature: ()Ljava/security/Provider; - */ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_createProvider(JNIEnv *env, jobject self) { /* Create the custom provider. */ jclass local_provider_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeProvider$Cryptopp"); @@ -100,11 +95,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_crea return env->NewObject(provider_class, init, name, version, info); } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp - * Method: setup - * Signature: ()V - */ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Cryptopp_setup(JNIEnv *env, jobject self){ jmethodID provider_put = env->GetMethodID(provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); @@ -157,11 +147,6 @@ static std::string oid_to_str(const OID &oid) { return ss.str(); } -/* - * Class: cz_crcs_ectester_standalone_libs_CryptoppLib - * Method: getCurves - * Signature: ()Ljava/util/Set; - */ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getCurves(JNIEnv *env, jobject self){ jclass set_class = env->FindClass("java/util/TreeSet"); @@ -180,11 +165,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getC return result; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp - * Method: keysizeSupported - * Signature: (I)Z - */ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_keysizeSupported(JNIEnv *env, jobject self, jint keysize){ std::vector<OID> ecp_oids = get_curve_oids<ECP>(); for (auto oid = ecp_oids.begin(); oid != ecp_oids.end(); ++oid) { @@ -204,11 +184,6 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa return JNI_FALSE; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp - * Method: paramsSupported - * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z - */ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_paramsSupported(JNIEnv *env, jobject self, jobject params){ if (params == NULL) { return JNI_FALSE; @@ -546,11 +521,6 @@ template <class EC> jobject generate_from_group(JNIEnv *env, DL_GroupParameters_ return env->NewObject(keypair_class, keypair_init, pubkey, privkey); } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp - * Method: generate - * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair; - */ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random){ std::vector<OID> ecp_oids = get_curve_oids<ECP>(); for (auto oid = ecp_oids.begin(); oid != ecp_oids.end(); ++oid) { @@ -572,11 +542,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai return NULL; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp - * Method: generate - * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair; - */ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random) { std::unique_ptr<DL_GroupParameters_EC<ECP>> ecp_group = fp_group_from_params(env, params); if (ecp_group == nullptr) { @@ -588,12 +553,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai return NULL; } - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Cryptopp - * Method: generateSecret - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B - */ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Cryptopp_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) { jsize privkey_length = env->GetArrayLength(privkey); jbyte *privkey_data = env->GetByteArrayElements(privkey, NULL); @@ -663,12 +622,6 @@ jbyteArray sign_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray return result; } - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp - * Method: sign - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B - */ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Cryptopp_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) { jclass cryptopp_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Cryptopp"); jfieldID type_id = env->GetFieldID(cryptopp_sig_class, "type", "Ljava/lang/String;"); @@ -715,7 +668,6 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig return result; } - template <class EC, class H> jboolean verify_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray data, jbyteArray signature, jbyteArray pubkey) { typename EC::Point pkey_point; @@ -739,11 +691,6 @@ jboolean verify_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray return result; } -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp - * Method: verify - * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z - */ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Cryptopp_verify(JNIEnv *env, jobject self, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params) { jclass cryptopp_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Cryptopp"); jfieldID type_id = env->GetFieldID(cryptopp_sig_class, "type", "Ljava/lang/String;"); diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h index 9385a4b..6aacdd3 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h @@ -513,3 +513,128 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna } #endif #endif +/* Header for class cz_crcs_ectester_standalone_libs_OpensslLib */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_OpensslLib +#define _Included_cz_crcs_ectester_standalone_libs_OpensslLib +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: cz_crcs_ectester_standalone_libs_OpensslLib + * Method: createProvider + * Signature: ()Ljava/security/Provider; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_createProvider + (JNIEnv *, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_OpensslLib + * Method: getCurves + * Signature: ()Ljava/util/Set; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_getCurves + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl +#ifdef __cplusplus +extern "C" { +#endif +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 1421746759512286392LL +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE 2147483639L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS 0L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_VALUES +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_VALUES 1L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES 2L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 4112578634029874840LL +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739LL +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl + * Method: setup + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Openssl_setup + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl + * Method: keysizeSupported + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_keysizeSupported + (JNIEnv *, jobject, jint); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl + * Method: paramsSupported + * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_paramsSupported + (JNIEnv *, jobject, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl + * Method: generate + * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__ILjava_security_SecureRandom_2 + (JNIEnv *, jobject, jint, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl + * Method: generate + * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2 + (JNIEnv *, jobject, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/cz/crcs/ectester/standalone/libs/jni/openssl.c b/src/cz/crcs/ectester/standalone/libs/jni/openssl.c new file mode 100644 index 0000000..ae6a222 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/libs/jni/openssl.c @@ -0,0 +1,393 @@ +#include "native.h" +#include <string.h> +#include <stdio.h> + +#include <openssl/conf.h> +#include <openssl/opensslv.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/ec.h> +#include <openssl/obj_mac.h> +#include <openssl/bn.h> + +#include "c_utils.h" + + +static jclass provider_class; + +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_createProvider(JNIEnv *env, jobject self) { + /* Create the custom provider. */ + jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Openssl"); + provider_class = (*env)->NewGlobalRef(env, local_provider_class); + + jmethodID init = (*env)->GetMethodID(env, local_provider_class, "<init>", "(Ljava/lang/String;DLjava/lang/String;)V"); + + jstring name = (*env)->NewStringUTF(env, OPENSSL_VERSION_TEXT); + double version = ((double)((OPENSSL_VERSION_NUMBER & 0xff000000L) >> 30)) + ((double)((OPENSSL_VERSION_NUMBER & 0xff0000L) >> 20)); + + return (*env)->NewObject(env, provider_class, init, name, version, name); +} + +JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Openssl_setup(JNIEnv *env, jobject self) { + OPENSSL_no_config(); + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + + jmethodID provider_put = (*env)->GetMethodID(env, provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + jstring ec = (*env)->NewStringUTF(env, "KeyPairGenerator.EC"); + jstring ec_value = (*env)->NewStringUTF(env, "cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$Openssl"); + (*env)->CallObjectMethod(env, self, provider_put, ec, ec_value); + + init_classes(env, "Openssl"); +} + +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_getCurves(JNIEnv *env, jobject self) { + jclass hash_set_class = (*env)->FindClass(env, "java/util/TreeSet"); + + jmethodID hash_set_ctr = (*env)->GetMethodID(env, hash_set_class, "<init>", "()V"); + jmethodID hash_set_add = (*env)->GetMethodID(env, hash_set_class, "add", "(Ljava/lang/Object;)Z"); + + jobject result = (*env)->NewObject(env, hash_set_class, hash_set_ctr); + + size_t ncurves = EC_get_builtin_curves(NULL, 0); + EC_builtin_curve curves[ncurves]; + EC_get_builtin_curves(curves, ncurves); + + for (size_t i = 0; i < ncurves; ++i) { + jstring curve_name = (*env)->NewStringUTF(env, OBJ_nid2sn(curves[i].nid)); + (*env)->CallBooleanMethod(env, result, hash_set_add, curve_name); + } + + return result; +} + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_keysizeSupported(JNIEnv *env, jobject self, jint keysize) { + size_t ncurves = EC_get_builtin_curves(NULL, 0); + EC_builtin_curve curves[ncurves]; + EC_get_builtin_curves(curves, ncurves); + + for (size_t i = 0; i < ncurves; ++i) { + EC_GROUP *curve = EC_GROUP_new_by_curve_name(curves[i].nid); + if (EC_GROUP_get_degree(curve) == keysize) { + EC_GROUP_clear_free(curve); + return JNI_TRUE; + } + EC_GROUP_free(curve); + } + return JNI_FALSE; +} + +static jobject bignum_to_biginteger(JNIEnv *env, const BIGNUM *bn) { + jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V"); + int size = BN_num_bytes(bn); + jbyteArray bytes = (*env)->NewByteArray(env, size); + jbyte *data = (*env)->GetByteArrayElements(env, bytes, NULL); + BN_bn2bin(bn, data); + (*env)->ReleaseByteArrayElements(env, bytes, data, JNI_COMMIT); + jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 0, bytes); + return result; +} + +static BIGNUM *biginteger_to_bignum(JNIEnv *env, jobject bigint) { + jmethodID to_byte_array = (*env)->GetMethodID(env, biginteger_class, "toByteArray", "()[B"); + + jbyteArray byte_array = (jbyteArray) (*env)->CallObjectMethod(env, bigint, to_byte_array); + jsize byte_length = (*env)->GetArrayLength(env, byte_array); + jbyte *byte_data = (*env)->GetByteArrayElements(env, byte_array, NULL); + BIGNUM *result = BN_bin2bn(byte_data, byte_length, NULL); + (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT); + return result; +} + +static EC_GROUP *create_curve(JNIEnv *env, jobject params) { + jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;"); + jobject elliptic_curve = (*env)->CallObjectMethod(env, params, get_curve); + + jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;"); + jobject field = (*env)->CallObjectMethod(env, elliptic_curve, get_field); + + jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I"); + jint bits = (*env)->CallIntMethod(env, field, get_bits); + jint bytes = (bits + 7) / 8; + + jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getA", "()Ljava/math/BigInteger;"); + jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a); + BIGNUM *a_bn = biginteger_to_bignum(env, a); + + jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;"); + jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b); + BIGNUM *b_bn = biginteger_to_bignum(env, b); + + jmethodID get_g = (*env)->GetMethodID(env, ec_parameter_spec_class, "getGenerator", "()Ljava/security/spec/ECPoint;"); + jobject g = (*env)->CallObjectMethod(env, params, get_g); + + jmethodID get_x = (*env)->GetMethodID(env, point_class, "getAffineX", "()Ljava/math/BigInteger;"); + jobject gx = (*env)->CallObjectMethod(env, g, get_x); + BIGNUM *gx_bn = biginteger_to_bignum(env, gx); + + jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;"); + jobject gy = (*env)->CallObjectMethod(env, g, get_y); + BIGNUM *gy_bn = biginteger_to_bignum(env, gy); + + EC_GROUP *result; + EC_POINT *g_point; + + if ((*env)->IsInstanceOf(env, field, fp_field_class)) { + jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;"); + jobject p = (*env)->CallObjectMethod(env, field, get_p); + + BIGNUM *p_bn = biginteger_to_bignum(env, p); + result = EC_GROUP_new_curve_GFp(p_bn, a_bn, b_bn, NULL); + BN_free(p_bn); + + g_point = EC_POINT_new(result); + EC_POINT_set_affine_coordinates_GFp(result, g_point, gx_bn, gy_bn, NULL); + } else if ((*env)->IsInstanceOf(env, field, f2m_field_class)) { + + jmethodID get_reduction_poly = (*env)->GetMethodID(env, f2m_field_class, "getReductionPolynomial", "()Ljava/math/BigInteger;"); + jobject red_poly = (*env)->CallObjectMethod(env, field, get_reduction_poly); + + BIGNUM *p_bn = biginteger_to_bignum(env, red_poly); + result = EC_GROUP_new_curve_GF2m(p_bn, a_bn, b_bn, NULL); + BN_free(p_bn); + + g_point = EC_POINT_new(result); + EC_POINT_set_affine_coordinates_GF2m(result, g_point, gx_bn, gy_bn, NULL); + } else { + return NULL; + } + + BN_free(a_bn); + BN_free(b_bn); + + jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;"); + jobject n = (*env)->CallObjectMethod(env, params, get_n); + BIGNUM *n_bn = biginteger_to_bignum(env, n); + + jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I"); + jint h = (*env)->CallIntMethod(env, params, get_h); + BIGNUM *h_bn = BN_new(); + BN_set_word(h_bn, h); + + EC_GROUP_set_generator(result, g_point, n_bn, h_bn); + + BN_free(gx_bn); + BN_free(gy_bn); + BN_free(n_bn); + BN_free(h_bn); + + return result; +} + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_paramsSupported(JNIEnv *env, jobject self, jobject params){ + if (params == NULL) { + return JNI_FALSE; + } + + if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) { + EC_GROUP *curve = create_curve(env, params); + jboolean result = (EC_GROUP_check(curve, NULL) == 1) ? JNI_TRUE : JNI_FALSE; + EC_GROUP_free(curve); + return result; + } else if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) { + jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;"); + jstring name = (*env)->CallObjectMethod(env, params, get_name); + const char *utf_name = (*env)->GetStringUTFChars(env, name, NULL); + size_t ncurves = EC_get_builtin_curves(NULL, 0); + EC_builtin_curve curves[ncurves]; + EC_get_builtin_curves(curves, ncurves); + for (size_t i = 0; i < ncurves; ++i) { + if (strcasecmp(utf_name, OBJ_nid2sn(curves[i].nid)) == 0) { + (*env)->ReleaseStringUTFChars(env, name, utf_name); + return JNI_TRUE; + } + } + (*env)->ReleaseStringUTFChars(env, name, utf_name); + return JNI_FALSE; + } else { + return JNI_FALSE; + } +} + +static jobject create_ec_param_spec(JNIEnv *env, const EC_GROUP *curve) { + int field_type = EC_METHOD_get_field_type(EC_GROUP_method_of(curve)); + BIGNUM *a; + BIGNUM *b; + + BIGNUM *gx; + BIGNUM *gy; + jobject field; + + if (field_type == NID_X9_62_prime_field) { + BIGNUM *p = BN_new(); + a = BN_new(); + b = BN_new(); + EC_GROUP_get_curve_GFp(curve, p, a, b, NULL); + + jobject p_int = bignum_to_biginteger(env, p); + + jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "<init>", "(Ljava/math/BigInteger;)V"); + field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int); + + BN_free(p); + + gx = BN_new(); + gy = BN_new(); + EC_POINT_get_affine_coordinates_GFp(curve, EC_GROUP_get0_generator(curve), gx, gy, NULL); + + } else if (field_type == NID_X9_62_characteristic_two_field) { + a = BN_new(); + b = BN_new(); + EC_GROUP_get_curve_GF2m(curve, NULL, a, b, NULL); + + int basis_type = EC_GROUP_get_basis_type(curve); + jintArray ks; + jint *ks_data; + if (basis_type == NID_X9_62_tpBasis) { + ks = (*env)->NewIntArray(env, 1); + ks_data = (*env)->GetIntArrayElements(env, ks, NULL); + EC_GROUP_get_trinomial_basis(curve, &ks_data[0]); + } else if (basis_type == NID_X9_62_ppBasis) { + ks = (*env)->NewIntArray(env, 3); + ks_data = (*env)->GetIntArrayElements(env, ks, NULL); + EC_GROUP_get_pentanomial_basis(curve, &ks_data[0], &ks_data[1], &ks_data[2]); + } else { + return NULL; + } + (*env)->ReleaseIntArrayElements(env, ks, ks_data, JNI_COMMIT); + + jint m = EC_GROUP_get_degree(curve); + + jmethodID f2m_field_init = (*env)->GetMethodID(env, f2m_field_class, "<init>", "(I[I)V"); + field = (*env)->NewObject(env, f2m_field_class, f2m_field_init, m, ks); + + gx = BN_new(); + gy = BN_new(); + EC_POINT_get_affine_coordinates_GF2m(curve, EC_GROUP_get0_generator(curve), gx, gy, NULL); + } else { + return NULL; + } + + jobject a_int = bignum_to_biginteger(env, a); + jobject b_int = bignum_to_biginteger(env, b); + + jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "<init>", "(Ljava/security/spec/ECField;Ljava/math/BigInteger;Ljava/math/BigInteger;)V"); + jobject elliptic_curve = (*env)->NewObject(env, elliptic_curve_class, elliptic_curve_init, field, a_int, b_int); + fprintf(stderr, "field: %p, a_int: %p, b_int: %p\n", field, a_int, b_int); + fflush(stderr); + + BN_free(a); + BN_free(b); + + jobject gx_int = bignum_to_biginteger(env, gx); + jobject gy_int = bignum_to_biginteger(env, gy); + + BN_free(gx); + BN_free(gy); + + jmethodID point_init = (*env)->GetMethodID(env, point_class, "<init>", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V"); + jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int); + + jobject order = bignum_to_biginteger(env, EC_GROUP_get0_order(curve)); + jint cofactor = BN_get_word(EC_GROUP_get0_cofactor(curve)); + + jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "<init>", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V"); + return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, order, cofactor); +} + +static jobject generate_from_curve(JNIEnv *env, const EC_GROUP *curve) { + jint keysize = EC_GROUP_get_degree(curve); + unsigned long key_bytes = (keysize + 7) / 8; + + EC_KEY *key = EC_KEY_new(); + EC_KEY_set_group(key, curve); + EC_KEY_generate_key(key); + + jbyteArray priv_bytes = (*env)->NewByteArray(env, key_bytes); + jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL); + BN_bn2binpad(EC_KEY_get0_private_key(key), key_priv, key_bytes); + (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, JNI_COMMIT); + + unsigned long key_len = 2*keysize + 1; + jbyteArray pub_bytes = (*env)->NewByteArray(env, key_len); + jbyte *key_pub = (*env)->GetByteArrayElements(env, pub_bytes, NULL); + EC_POINT_point2oct(curve, EC_KEY_get0_public_key(key), POINT_CONVERSION_UNCOMPRESSED, key_pub, key_len, NULL); + (*env)->ReleaseByteArrayElements(env, pub_bytes, key_pub, JNI_COMMIT); + + EC_KEY_free(key); + + jobject ec_param_spec = create_ec_param_spec(env, curve); + + jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec); + jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "<init>", "([BLjava/security/spec/ECParameterSpec;)V"); + jobject pubkey = (*env)->NewObject(env, pubkey_class, ec_pub_init, pub_bytes, ec_param_spec); + + jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec); + jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "<init>", "([BLjava/security/spec/ECParameterSpec;)V"); + jobject privkey = (*env)->NewObject(env, privkey_class, ec_priv_init, priv_bytes, ec_priv_param_spec); + + jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "<init>", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V"); + return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey); +} + +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) { + size_t ncurves = EC_get_builtin_curves(NULL, 0); + EC_builtin_curve curves[ncurves]; + EC_get_builtin_curves(curves, ncurves); + + EC_GROUP *curve = NULL; + for (size_t i = 0; i < ncurves; ++i) { + curve = EC_GROUP_new_by_curve_name(curves[i].nid); + if (EC_GROUP_get_degree(curve) == keysize) { + break; + } + EC_GROUP_free(curve); + } + + if (!curve) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve for given bitsize not found."); + return NULL; + } + + jobject result = generate_from_curve(env, curve); + EC_GROUP_free(curve); + return result; +} + + + +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random) { + if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) { + EC_GROUP *curve = create_curve(env, params); + jobject result = generate_from_curve(env, curve); + EC_GROUP_free(curve); + return result; + } else if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) { + jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;"); + jstring name = (*env)->CallObjectMethod(env, params, get_name); + const char* utf_name = (*env)->GetStringUTFChars(env, name, NULL); + size_t ncurves = EC_get_builtin_curves(NULL, 0); + EC_builtin_curve curves[ncurves]; + EC_get_builtin_curves(curves, ncurves); + EC_GROUP *curve; + for (size_t i = 0; i < ncurves; ++i) { + if (strcasecmp(utf_name, OBJ_nid2sn(curves[i].nid)) == 0) { + curve = EC_GROUP_new_by_curve_name(curves[i].nid); + break; + } + } + (*env)->ReleaseStringUTFChars(env, name, utf_name); + if (!curve) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve for given bitsize not found."); + return NULL; + } + jobject result = generate_from_curve(env, curve); + EC_GROUP_free(curve); + return result; + } else { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return NULL; + } +}
\ No newline at end of file diff --git a/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c b/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c index 29ee707..dc3abd9 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c @@ -128,6 +128,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa } curve++; } + (*env)->ReleaseStringUTFChars(env, name, utf_name); return JNI_FALSE; } else { return JNI_FALSE; diff --git a/src/cz/crcs/ectester/standalone/output/TextTestWriter.java b/src/cz/crcs/ectester/standalone/output/TextTestWriter.java index 2e29b07..93be3a8 100644 --- a/src/cz/crcs/ectester/standalone/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/standalone/output/TextTestWriter.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.standalone.output; +import cz.crcs.ectester.common.cli.Colors; import cz.crcs.ectester.common.output.BaseTextTestWriter; import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.test.Testable; @@ -45,8 +46,8 @@ public class TextTestWriter extends BaseTextTestWriter { if (suite instanceof StandaloneTestSuite) { StandaloneTestSuite standaloneSuite = (StandaloneTestSuite) suite; StringBuilder sb = new StringBuilder(); - sb.append("═══ ECTester version: " + ECTesterStandalone.VERSION).append(System.lineSeparator()); - sb.append("═══ ").append(standaloneSuite.getLibrary().name()).append(System.lineSeparator()); + sb.append("═══ ").append(Colors.underline("ECTester version:")).append(" ").append(ECTesterStandalone.VERSION).append(System.lineSeparator()); + sb.append("═══ ").append(Colors.underline("Library:")).append(standaloneSuite.getLibrary().name()).append(System.lineSeparator()); return sb.toString(); } return ""; |
