diff --git a/src/main/java/org/apache/commons/crypto/cipher/CryptoCipherFactory.java b/src/main/java/org/apache/commons/crypto/cipher/CryptoCipherFactory.java index 8824b3265..0851b0b88 100644 --- a/src/main/java/org/apache/commons/crypto/cipher/CryptoCipherFactory.java +++ b/src/main/java/org/apache/commons/crypto/cipher/CryptoCipherFactory.java @@ -35,6 +35,13 @@ public class CryptoCipherFactory { */ public static final String JCE_PROVIDER_KEY = Crypto.CONF_PREFIX + "cipher.jce.provider"; + + /** + * The configuration key of the engineId for OpenSSL. + */ + public static final String CIPHER_ENGINE_KEY = Crypto.CONF_PREFIX + + "cipher.engine"; + /** * The configuration key of the CryptoCipher implementation class. *
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java index c8f3d98ab..3f3ccab06 100644 --- a/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java +++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java @@ -378,4 +378,12 @@ protected void finalize() throws Throwable { clean(); } + /** + * Use engine by default for symmetric cipher operations. + * + * @param engineId the id of engine + */ + public void engineSetDefaultCiphers(String engineId) { + opensslBlockCipher.engineSetDefaultCiphers(engineId); + } } diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSslCipher.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSslCipher.java index 50e73da9b..53d511c60 100644 --- a/src/main/java/org/apache/commons/crypto/cipher/OpenSslCipher.java +++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSslCipher.java @@ -60,6 +60,11 @@ public OpenSslCipher(final Properties props, final String transformation) // NOP } openSslEngine = OpenSsl.getInstance(transformation); + + String engineId = props.getProperty(CryptoCipherFactory.CIPHER_ENGINE_KEY); + if (engineId != null && !engineId.isEmpty()) { + openSslEngine.engineSetDefaultCiphers(engineId); + } } /** diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSslCommonMode.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSslCommonMode.java index 6ca17bb90..e6136693d 100644 --- a/src/main/java/org/apache/commons/crypto/cipher/OpenSslCommonMode.java +++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSslCommonMode.java @@ -116,4 +116,9 @@ public void updateAAD(final byte[] aad) { "The underlying Cipher implementation " + "does not support this method"); } + + @Override + public void engineSetDefaultCiphers(String engineId) { + OpenSslNative.engineSetDefaultCiphers(engineId); + } } diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSslFeedbackCipher.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSslFeedbackCipher.java index b49ba4954..69f7c1441 100644 --- a/src/main/java/org/apache/commons/crypto/cipher/OpenSslFeedbackCipher.java +++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSslFeedbackCipher.java @@ -61,6 +61,8 @@ abstract int doFinal(ByteBuffer input, ByteBuffer output) throws ShortBufferExce abstract void updateAAD(byte[] aad); + abstract void engineSetDefaultCiphers(String engineId); + public void clean() { if (context != 0) { OpenSslNative.clean(context); diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSslGaloisCounterMode.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSslGaloisCounterMode.java index 79950edaf..75e0c644c 100644 --- a/src/main/java/org/apache/commons/crypto/cipher/OpenSslGaloisCounterMode.java +++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSslGaloisCounterMode.java @@ -279,6 +279,11 @@ public void updateAAD(final byte[] aad) { } } + @Override + public void engineSetDefaultCiphers(String engineId) { + OpenSslNative.engineSetDefaultCiphers(engineId); + } + private void processAAD() { if (aadBuffer != null && aadBuffer.size() > 0) { OpenSslNative.updateByteArray(context, aadBuffer.toByteArray(), diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java index cb6136228..b39d59db8 100644 --- a/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java +++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java @@ -159,4 +159,11 @@ public native static int doFinalByteArray(long context, byte[] output, * @param context The cipher context address */ public native static void clean(long context); + + /** + * Use engine by default for symmetric cipher operations. + * + * @param engineId The id of engine + */ + public native static void engineSetDefaultCiphers(String engineId); } diff --git a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c index 2204d0a19..f71eae979 100644 --- a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c +++ b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c @@ -52,6 +52,11 @@ static EVP_CIPHER * (*dlsym_EVP_aes_128_cbc)(void); static EVP_CIPHER * (*dlsym_EVP_aes_256_gcm)(void); static EVP_CIPHER * (*dlsym_EVP_aes_192_gcm)(void); static EVP_CIPHER * (*dlsym_EVP_aes_128_gcm)(void); +static ENGINE * (*dlsym_ENGINE_by_id) (const char *); +static int (*dlsym_ENGINE_init) (ENGINE *); +static int (*dlsym_ENGINE_finish) (ENGINE *); +static int (*dlsym_ENGINE_free) (ENGINE *); +static int (*dlsym_ENGINE_set_default_ciphers) (ENGINE *); #endif #ifdef WINDOWS @@ -79,6 +84,11 @@ typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_cbc)(void); typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_gcm)(void); typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_gcm)(void); typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_gcm)(void); +typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id)(const char *); +typedef int (__cdecl *__dlsym_ENGINE_init)(ENGINE *); +typedef int (__cdecl *__dlsym_ENGINE_finish)(ENGINE *); +typedef int (__cdecl *__dlsym_ENGINE_free)(ENGINE *); +typedef int (__cdecl *__dlsym_ENGINE_set_default_ciphers)(ENGINE *); static __dlsym_EVP_CIPHER_CTX_new dlsym_EVP_CIPHER_CTX_new; static __dlsym_EVP_CIPHER_CTX_free dlsym_EVP_CIPHER_CTX_free; static __dlsym_EVP_CIPHER_CTX_set_padding dlsym_EVP_CIPHER_CTX_set_padding; @@ -99,6 +109,11 @@ static __dlsym_EVP_aes_128_cbc dlsym_EVP_aes_128_cbc; static __dlsym_EVP_aes_256_gcm dlsym_EVP_aes_256_gcm; static __dlsym_EVP_aes_192_gcm dlsym_EVP_aes_192_gcm; static __dlsym_EVP_aes_128_gcm dlsym_EVP_aes_128_gcm; +static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id; +static __dlsym_ENGINE_init dlsym_ENGINE_init; +static __dlsym_ENGINE_finish dlsym_ENGINE_finish; +static __dlsym_ENGINE_free dlsym_ENGINE_free; +static __dlsym_ENGINE_set_default_ciphers dlsym_ENGINE_set_default_ciphers; #endif #ifdef UNIX @@ -181,6 +196,11 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherInit_ex, env, openssl, "EVP_CipherInit_ex"); LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherUpdate, env, openssl, "EVP_CipherUpdate"); LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherFinal_ex, env, openssl, "EVP_CipherFinal_ex"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_by_id, env, openssl, "ENGINE_by_id"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_init, env, openssl, "ENGINE_init"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_finish, env, openssl, "ENGINE_finish"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_set_default_ciphers, env, openssl, "ENGINE_set_default_ciphers"); #endif #ifdef WINDOWS @@ -206,6 +226,17 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI env, openssl, "EVP_CipherUpdate"); LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherFinal_ex, dlsym_EVP_CipherFinal_ex, \ env, openssl, "EVP_CipherFinal_ex"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id, \ + env, openssl, "ENGINE_by_id"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_init, dlsym_ENGINE_init, \ + env, openssl, "ENGINE_init"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_finish, dlsym_ENGINE_finish, \ + env, openssl, "ENGINE_finish"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, \ + env, openssl, "ENGINE_free"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_set_default_ciphers, dlsym_ENGINE_set_default_ciphers, \ + env, openssl, "ENGINE_set_default_ciphers"); + #endif loadAes(env, openssl); @@ -688,6 +719,35 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_clean free_context_wrapper(wrapper); } +JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_engineSetDefaultCiphers + (JNIEnv *env, jclass clazz, jstring engineId) +{ + const char* eId = (*env)->GetStringUTFChars(env, engineId, 0); + ENGINE *e = dlsym_ENGINE_by_id(eId); + + if (!e) { + char msg[64] = {0}; + snprintf(msg, sizeof(msg), "Not found engine: %s", eId); + THROW(env, "java/lang/InternalError", msg); + return; + } + (*env)->ReleaseStringUTFChars(env, engineId, eId); + + if (dlsym_ENGINE_init(e) != 1) { + dlsym_ENGINE_free(e); + THROW(env, "java/lang/InternalError", "Error in ENGINE_init."); + return; + } + + if (dlsym_ENGINE_set_default_ciphers(e) != 1) { + THROW(env, "java/lang/InternalError", "Error in ENGINE_set_default_ciphers."); + return; + } + dlsym_ENGINE_finish(e); + dlsym_ENGINE_free(e); + return; +} + static int check_update_max_output_len(EVP_CTX_Wrapper *wrapper, int input_len, int max_output_len) { if (dlsym_EVP_CIPHER_CTX_test_flags(wrapper->ctx, EVP_CIPH_NO_PADDING) == EVP_CIPH_NO_PADDING) {