You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by va...@apache.org on 2019/02/19 18:40:54 UTC
[commons-crypto] branch master updated: OpenSSL 1.1.0 updates with
backward compatibility for OpenSSL 1.0.2 and 1.0.1 (#92)
This is an automated email from the ASF dual-hosted git repository.
vanzin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-crypto.git
The following commit(s) were added to refs/heads/master by this push:
new 2875340 OpenSSL 1.1.0 updates with backward compatibility for OpenSSL 1.0.2 and 1.0.1 (#92)
2875340 is described below
commit 2875340ca3f9f5b19cd14939d9c0fbba500687f1
Author: aremily <ar...@users.noreply.github.com>
AuthorDate: Tue Feb 19 13:40:39 2019 -0500
OpenSSL 1.1.0 updates with backward compatibility for OpenSSL 1.0.2 and 1.0.1 (#92)
---
Makefile.common | 6 +-
.../java/org/apache/commons/crypto/Crypto.java | 8 +-
.../apache/commons/crypto/OpenSslInfoNative.java | 19 +-
...nSslNativeJna.java => OpenSsl10XNativeJna.java} | 180 ++++----
...nSslNativeJna.java => OpenSsl11XNativeJna.java} | 212 ++++-----
.../org/apache/commons/crypto/jna/OpenSslJna.java | 10 +
.../commons/crypto/jna/OpenSslJnaCryptoRandom.java | 2 +-
.../commons/crypto/jna/OpenSslNativeJna.java | 477 ++++++++++-----------
.../org/apache/commons/crypto/OpenSslInfoNative.c | 83 ++--
.../apache/commons/crypto/cipher/OpenSslNative.c | 163 +++----
.../commons/crypto/org_apache_commons_crypto.h | 22 +
.../crypto/random/OpenSslCryptoRandomNative.c | 86 ++--
.../commons/crypto/jna/OpenSslNativeJnaTest.java | 2 +-
13 files changed, 638 insertions(+), 632 deletions(-)
diff --git a/Makefile.common b/Makefile.common
index 96a53b8..f5ce5b7 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -179,10 +179,10 @@ Mac-x86_LIBNAME := libcommons-crypto.jnilib
Mac-x86_COMMONS_CRYPTO_FLAGS :=
Mac-x86_64_CC := gcc -arch $(OS_ARCH)
-Mac-x86_64_CXX := g++ -arch $(OS_ARCH)
+Mac-x86_64_CXX := gcc -arch $(OS_ARCH)
Mac-x86_64_STRIP := strip -x
-Mac-x86_64_CFLAGS := -Ilib/inc_mac -I$(JAVA_HOME)/include -O2 -fPIC -mmacosx-version-min=10.5 -fvisibility=hidden -I/usr/local/include -I/usr/local/opt/openssl/include
-Mac-x86_64_CXXFLAGS := -Ilib/inc_mac -I$(JAVA_HOME)/include -O2 -fPIC -mmacosx-version-min=10.5 -fvisibility=hidden -I/usr/local/include -I/usr/local/opt/openssl/include
+Mac-x86_64_CFLAGS := -Ilib/inc_mac -I$(JAVA_HOME)/include -O2 -fPIC -mmacosx-version-min=10.7 -fvisibility=hidden -I/usr/local/include -I/usr/local/opt/openssl/include
+Mac-x86_64_CXXFLAGS := -Ilib/inc_mac -I$(JAVA_HOME)/include -O2 -fPIC -mmacosx-version-min=10.7 -fvisibility=hidden -I/usr/local/include -I/usr/local/opt/openssl/include
Mac-x86_64_LINKFLAGS := -dynamiclib -L/usr/local/lib
Mac-x86_64_LIBNAME := libcommons-crypto.jnilib
Mac-x86_64_COMMONS_CRYPTO_FLAGS :=
diff --git a/src/main/java/org/apache/commons/crypto/Crypto.java b/src/main/java/org/apache/commons/crypto/Crypto.java
index 48069f4..b6fc886 100644
--- a/src/main/java/org/apache/commons/crypto/Crypto.java
+++ b/src/main/java/org/apache/commons/crypto/Crypto.java
@@ -132,8 +132,8 @@ public final class Crypto {
System.out.println("Native code loaded OK " + OpenSslInfoNative.NativeVersion());
System.out.println("Native Name " + OpenSslInfoNative.NativeName());
System.out.println("Native Built " + OpenSslInfoNative.NativeTimeStamp());
- System.out.println("OpenSSL library loaded OK, version: 0x" + Long.toHexString(OpenSslInfoNative.SSLeay()));
- System.out.println(OpenSslInfoNative.SSLeayVersion(0));
+ System.out.println("OpenSSL library loaded OK, version: 0x" + Long.toHexString(OpenSslInfoNative.OpenSSL()));
+ System.out.println("OpenSSL library info " + OpenSslInfoNative.OpenSSLVersion(0));
{
Properties props = new Properties();
props.setProperty(CryptoRandomFactory.CLASSES_KEY, CryptoRandomFactory.RandomProvider.OPENSSL.getClassName());
@@ -146,9 +146,9 @@ public final class Crypto {
CryptoCipherFactory.getCryptoCipher("AES/CTR/NoPadding", props);
System.out.println("Cipher instance created OK");
}
- System.out.println("Additional SSLeay_version(n) details:");
+ System.out.println("Additional OpenSSL_version(n) details:");
for(int j=1;j<6;j++) {
- System.out.println(j+": "+ OpenSslInfoNative.SSLeayVersion(j));
+ System.out.println(j+": "+ OpenSslInfoNative.OpenSSLVersion(j));
}
} else {
System.out.println("Native load failed: " + getLoadingError());
diff --git a/src/main/java/org/apache/commons/crypto/OpenSslInfoNative.java b/src/main/java/org/apache/commons/crypto/OpenSslInfoNative.java
index 8ca2fde..85a3687 100644
--- a/src/main/java/org/apache/commons/crypto/OpenSslInfoNative.java
+++ b/src/main/java/org/apache/commons/crypto/OpenSslInfoNative.java
@@ -18,7 +18,7 @@
package org.apache.commons.crypto;
/**
- * JNI interface of {@see CryptoRandom} implementation for OpenSSL.
+ * JNI interface of {@link CryptoRandom} implementation for OpenSSL.
* The native method in this class is defined in
* OpenSslCryptoRandomNative.h (generated at build time by javah)
* and implemented in the file
@@ -26,6 +26,9 @@ package org.apache.commons.crypto;
*/
class OpenSslInfoNative {
+ public static final long VERSION_1_0_2X = 0x10002000;
+ public static final long VERSION_1_1_0X = 0x10100000;
+
/**
* Makes the constructor private.
*/
@@ -46,16 +49,18 @@ class OpenSslInfoNative {
* @return timestamp of native
*/
public static native String NativeTimeStamp();
-
+
+
/**
- * @return the value of SSLEAY_VERSION_NUMBER.
+ * @return the value of OPENSSL_VERSION_NUMBER.
*/
- public static native long SSLeay();
-
+ public static native long OpenSSL();
+
/**
- * Returns SSLeay_version according the version type.
+ * Returns OpenSSL_version according the version type.
+ *
* @param type The version type
* @return The text variant of the version number and the release date.
*/
- public static native String SSLeayVersion(int type);
+ public static native String OpenSSLVersion(int type);
}
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java b/src/main/java/org/apache/commons/crypto/jna/OpenSsl10XNativeJna.java
similarity index 69%
copy from src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
copy to src/main/java/org/apache/commons/crypto/jna/OpenSsl10XNativeJna.java
index 099c049..ed050b2 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSsl10XNativeJna.java
@@ -24,12 +24,7 @@ import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.PointerByReference;
-class OpenSslNativeJna {
-
- static final int OPENSSL_INIT_ENGINE_RDRAND = 0x00000200;
-
- static final int OOSL_JNA_ENCRYPT_MODE = 1;
- static final int OOSL_JNA_DECRYPT_MODE = 0;
+class OpenSsl10XNativeJna {
static final boolean INIT_OK;
@@ -40,7 +35,6 @@ class OpenSslNativeJna {
Throwable thrown = null;
try {
Native.register("crypto");
- ERR_load_crypto_strings();
ok = true;
} catch (Exception e) {
thrown = e;
@@ -52,19 +46,18 @@ class OpenSslNativeJna {
}
}
- //misc
/**
- * @return OPENSSL_VERSION_NUMBER which is a numeric release version
- * * identifier
+ * @return OPENSSL_VERSION_NUMBER which is a numeric release version identifier
*/
public static native NativeLong SSLeay();
/**
* Retrieves version/build information about OpenSSL library.
*
- * @param type type can be SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON...
- * @return A pointer to a constant string describing the version of the
- * OpenSSL library or giving information about the library build.
+ * @param type
+ * type can be SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON...
+ * @return A pointer to a constant string describing the version of the OpenSSL library or
+ * giving information about the library build.
*/
public static native String SSLeay_version(int type);
@@ -74,45 +67,45 @@ class OpenSslNativeJna {
public static native void ERR_load_crypto_strings();
/**
- * @return the earliest error code from the thread's error queue without
- * modifying it.
+ * @return the earliest error code from the thread's error queue without modifying it.
*/
public static native NativeLong ERR_peek_error();
-
-
/**
* Generates a human-readable string representing the error code e.
+ *
* @see <a>https://www.openssl.org/docs/manmaster/crypto/ERR_error_string.html</a>
*
- * @param err the error code
- * @param null_ buf is NULL, the error string is placed in a static buffer
+ * @param err
+ * the error code
+ * @param null_
+ * buf is NULL, the error string is placed in a static buffer
* @return the human-readable error messages.
*/
public static native String ERR_error_string(NativeLong err, char[] null_);
- //String ERR_lib_error_string(NativeLong err);
- //String ERR_func_error_string(NativeLong err);
- //en-/decryption
/**
* Creates a cipher context.
*
- * @return a pointer to a newly created EVP_CIPHER_CTX for success and
- * NULL for failure.
+ * @return a pointer to a newly created EVP_CIPHER_CTX for success and NULL for failure.
*/
public static native PointerByReference EVP_CIPHER_CTX_new();
-
/**
* EVP_CIPHER_CTX_init() remains as an alias for EVP_CIPHER_CTX_reset
- * @param p cipher context
+ *
+ * @param p
+ * cipher context
*/
public static native void EVP_CIPHER_CTX_init(PointerByReference p);
/**
* Enables or disables padding
- * @param c cipher context
- * @param pad If the pad parameter is zero then no padding is performed
+ *
+ * @param c
+ * cipher context
+ * @param pad
+ * If the pad parameter is zero then no padding is performed
* @return always returns 1
*/
public static native int EVP_CIPHER_CTX_set_padding(PointerByReference c, int pad);
@@ -149,70 +142,96 @@ class OpenSslNativeJna {
/**
* Init a cipher.
- * @param ctx cipher context
- * @param cipher evp cipher instance
- * @param impl engine
- * @param key key
- * @param iv iv
- * @param enc 1 for encryption, 0 for decryption
+ *
+ * @param ctx
+ * cipher context
+ * @param cipher
+ * evp cipher instance
+ * @param impl
+ * engine
+ * @param key
+ * key
+ * @param iv
+ * iv
+ * @param enc
+ * 1 for encryption, 0 for decryption
* @return 1 for success and 0 for failure.
*/
- public static native int EVP_CipherInit_ex(PointerByReference ctx, PointerByReference cipher, PointerByReference impl, byte key[], byte iv[], int enc);
-
+ public static native int EVP_CipherInit_ex(PointerByReference ctx, PointerByReference cipher,
+ PointerByReference impl, byte key[], byte iv[], int enc);
/**
* Continues a multiple-part encryption/decryption operation.
*
- * @param ctx cipher context
- * @param bout output byte buffer
- * @param outl output length
- * @param in input byte buffer
- * @param inl input length
+ * @param ctx
+ * cipher context
+ * @param bout
+ * output byte buffer
+ * @param outl
+ * output length
+ * @param in
+ * input byte buffer
+ * @param inl
+ * input length
* @return 1 for success and 0 for failure.
*/
- public static native int EVP_CipherUpdate(PointerByReference ctx, ByteBuffer bout, int[] outl, ByteBuffer in, int inl);
+ public static native int EVP_CipherUpdate(PointerByReference ctx, ByteBuffer bout, int[] outl,
+ ByteBuffer in, int inl);
/**
* Finishes a multiple-part operation.
*
- * @param ctx cipher context
- * @param bout output byte buffer
- * @param outl output length
+ * @param ctx
+ * cipher context
+ * @param bout
+ * output byte buffer
+ * @param outl
+ * output length
* @return 1 for success and 0 for failure.
*/
- public static native int EVP_CipherFinal_ex(PointerByReference ctx, ByteBuffer bout, int[] outl);
+ public static native int EVP_CipherFinal_ex(PointerByReference ctx, ByteBuffer bout,
+ int[] outl);
/**
- * Clears all information from a cipher context and free up any allocated
- * memory associate with it, including ctx itself.
- * @param c openssl evp cipher
+ * Clears all information from a cipher context and free up any allocated memory associate with
+ * it, including ctx itself.
+ *
+ * @param c
+ * openssl evp cipher
*/
public static native void EVP_CIPHER_CTX_free(PointerByReference c);
/**
- * Clears all information from a cipher context and free up any allocated
- * * memory associate with it.
- * @param c openssl evp cipher
+ * Clears all information from a cipher context and free up any allocated * memory associate
+ * with it.
+ *
+ * @param c
+ * openssl evp cipher
*/
public static native void EVP_CIPHER_CTX_cleanup(PointerByReference c);
- //Random generator
+ // Random generator
/**
* OpenSSL uses for random number generation
+ *
* @return pointers to the respective methods
*/
public static native PointerByReference RAND_get_rand_method();
/**
* OpenSSL uses for random number generation.
+ *
* @return pointers to the respective methods
*/
public static native PointerByReference RAND_SSLeay();
/**
* Generates random data
- * @param buf the bytes for generated random.
- * @param num buffer length
+ *
+ * @param buf
+ * the bytes for generated random.
+ * @param num
+ * buffer length
* @return 1 on success, 0 otherwise.
*/
public static native int RAND_bytes(ByteBuffer buf, int num);
@@ -220,42 +239,54 @@ class OpenSslNativeJna {
/**
* Releases all functional references.
*
- * @param e engine reference.
+ * @param e
+ * engine reference.
* @return 0 on success, 1 otherwise.
*/
public static native int ENGINE_finish(PointerByReference e);
/**
* Frees the structural reference
- * @param e engine reference.
+ *
+ * @param e
+ * engine reference.
* @return 0 on success, 1 otherwise.
*/
public static native int ENGINE_free(PointerByReference e);
/**
* Cleanups before program exit, it will avoid memory leaks.
+ *
* @return 0 on success, 1 otherwise.
*/
public static native int ENGINE_cleanup();
/**
* Obtains a functional reference from an existing structural reference.
- * @param e engine reference
- * @return zero if the ENGINE was not already operational and couldn't be successfully initialised
+ *
+ * @param e
+ * engine reference
+ * @return zero if the ENGINE was not already operational and couldn't be successfully
+ * initialised
*/
public static native int ENGINE_init(PointerByReference e);
/**
* Sets the engine as the default for random number generation.
- * @param e engine reference
- * @param flags ENGINE_METHOD_RAND
+ *
+ * @param e
+ * engine reference
+ * @param flags
+ * ENGINE_METHOD_RAND
* @return zero if failed.
*/
public static native int ENGINE_set_default(PointerByReference e, int flags);
/**
* Gets engine by id
- * @param id engine id
+ *
+ * @param id
+ * engine id
* @return engine instance
*/
public static native PointerByReference ENGINE_by_id(String id);
@@ -264,27 +295,4 @@ class OpenSslNativeJna {
* Initializes the engine.
*/
public static native void ENGINE_load_rdrand();
-
- //TODO callback multithreading
- /*public interface Id_function_cb extends Callback {
- long invoke ();
- }
-
- public interface Locking_function_cb extends Callback {
- void invoke(int mode, int n, String file, int line);
- }
-
- public static final Id_function_cb default_id_function = new Id_function_cb() {
-
- @Override
- public long invoke() {
- //id always positive
- long id = Thread.currentThread().getId();
- return id;
- }
- };
-
- int CRYPTO_num_locks();
- void CRYPTO_set_id_callback(Id_function_cb id_function);
- void CRYPTO_set_locking_callback(Locking_function_cb locking_function);*/
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java b/src/main/java/org/apache/commons/crypto/jna/OpenSsl11XNativeJna.java
similarity index 58%
copy from src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
copy to src/main/java/org/apache/commons/crypto/jna/OpenSsl11XNativeJna.java
index 099c049..b9c4c0e 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSsl11XNativeJna.java
@@ -24,12 +24,7 @@ import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.PointerByReference;
-class OpenSslNativeJna {
-
- static final int OPENSSL_INIT_ENGINE_RDRAND = 0x00000200;
-
- static final int OOSL_JNA_ENCRYPT_MODE = 1;
- static final int OOSL_JNA_DECRYPT_MODE = 0;
+class OpenSsl11XNativeJna {
static final boolean INIT_OK;
@@ -40,7 +35,6 @@ class OpenSslNativeJna {
Throwable thrown = null;
try {
Native.register("crypto");
- ERR_load_crypto_strings();
ok = true;
} catch (Exception e) {
thrown = e;
@@ -52,67 +46,38 @@ class OpenSslNativeJna {
}
}
- //misc
- /**
- * @return OPENSSL_VERSION_NUMBER which is a numeric release version
- * * identifier
- */
- public static native NativeLong SSLeay();
-
- /**
- * Retrieves version/build information about OpenSSL library.
- *
- * @param type type can be SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON...
- * @return A pointer to a constant string describing the version of the
- * OpenSSL library or giving information about the library build.
- */
- public static native String SSLeay_version(int type);
-
/**
- * Registers the error strings for all libcrypto functions.
- */
- public static native void ERR_load_crypto_strings();
-
- /**
- * @return the earliest error code from the thread's error queue without
- * modifying it.
+ * @return the earliest error code from the thread's error queue without modifying it.
*/
public static native NativeLong ERR_peek_error();
-
-
/**
* Generates a human-readable string representing the error code e.
+ *
* @see <a>https://www.openssl.org/docs/manmaster/crypto/ERR_error_string.html</a>
*
- * @param err the error code
- * @param null_ buf is NULL, the error string is placed in a static buffer
+ * @param err
+ * the error code
+ * @param null_
+ * buf is NULL, the error string is placed in a static buffer
* @return the human-readable error messages.
*/
public static native String ERR_error_string(NativeLong err, char[] null_);
- //String ERR_lib_error_string(NativeLong err);
- //String ERR_func_error_string(NativeLong err);
- //en-/decryption
/**
* Creates a cipher context.
*
- * @return a pointer to a newly created EVP_CIPHER_CTX for success and
- * NULL for failure.
+ * @return a pointer to a newly created EVP_CIPHER_CTX for success and NULL for failure.
*/
public static native PointerByReference EVP_CIPHER_CTX_new();
-
- /**
- * EVP_CIPHER_CTX_init() remains as an alias for EVP_CIPHER_CTX_reset
- * @param p cipher context
- */
- public static native void EVP_CIPHER_CTX_init(PointerByReference p);
-
/**
* Enables or disables padding
- * @param c cipher context
- * @param pad If the pad parameter is zero then no padding is performed
+ *
+ * @param c
+ * cipher context
+ * @param pad
+ * If the pad parameter is zero then no padding is performed
* @return always returns 1
*/
public static native int EVP_CIPHER_CTX_set_padding(PointerByReference c, int pad);
@@ -149,70 +114,88 @@ class OpenSslNativeJna {
/**
* Init a cipher.
- * @param ctx cipher context
- * @param cipher evp cipher instance
- * @param impl engine
- * @param key key
- * @param iv iv
- * @param enc 1 for encryption, 0 for decryption
+ *
+ * @param ctx
+ * cipher context
+ * @param cipher
+ * evp cipher instance
+ * @param impl
+ * engine
+ * @param key
+ * key
+ * @param iv
+ * iv
+ * @param enc
+ * 1 for encryption, 0 for decryption
* @return 1 for success and 0 for failure.
*/
- public static native int EVP_CipherInit_ex(PointerByReference ctx, PointerByReference cipher, PointerByReference impl, byte key[], byte iv[], int enc);
-
+ public static native int EVP_CipherInit_ex(PointerByReference ctx, PointerByReference cipher,
+ PointerByReference impl, byte key[], byte iv[], int enc);
/**
* Continues a multiple-part encryption/decryption operation.
*
- * @param ctx cipher context
- * @param bout output byte buffer
- * @param outl output length
- * @param in input byte buffer
- * @param inl input length
+ * @param ctx
+ * cipher context
+ * @param bout
+ * output byte buffer
+ * @param outl
+ * output length
+ * @param in
+ * input byte buffer
+ * @param inl
+ * input length
* @return 1 for success and 0 for failure.
*/
- public static native int EVP_CipherUpdate(PointerByReference ctx, ByteBuffer bout, int[] outl, ByteBuffer in, int inl);
+ public static native int EVP_CipherUpdate(PointerByReference ctx, ByteBuffer bout, int[] outl,
+ ByteBuffer in, int inl);
/**
* Finishes a multiple-part operation.
*
- * @param ctx cipher context
- * @param bout output byte buffer
- * @param outl output length
+ * @param ctx
+ * cipher context
+ * @param bout
+ * output byte buffer
+ * @param outl
+ * output length
* @return 1 for success and 0 for failure.
*/
- public static native int EVP_CipherFinal_ex(PointerByReference ctx, ByteBuffer bout, int[] outl);
+ public static native int EVP_CipherFinal_ex(PointerByReference ctx, ByteBuffer bout,
+ int[] outl);
/**
- * Clears all information from a cipher context and free up any allocated
- * memory associate with it, including ctx itself.
- * @param c openssl evp cipher
+ * Clears all information from a cipher context and free up any allocated memory associate with
+ * it, including ctx itself.
+ *
+ * @param c
+ * openssl evp cipher
*/
public static native void EVP_CIPHER_CTX_free(PointerByReference c);
/**
- * Clears all information from a cipher context and free up any allocated
- * * memory associate with it.
- * @param c openssl evp cipher
+ * Clears all information from a cipher context and free up any allocated * memory associate
+ * with it.
+ *
+ * @param c
+ * openssl evp cipher
*/
- public static native void EVP_CIPHER_CTX_cleanup(PointerByReference c);
- //Random generator
+ // Random generator
/**
* OpenSSL uses for random number generation
+ *
* @return pointers to the respective methods
*/
public static native PointerByReference RAND_get_rand_method();
/**
- * OpenSSL uses for random number generation.
- * @return pointers to the respective methods
- */
- public static native PointerByReference RAND_SSLeay();
-
- /**
* Generates random data
- * @param buf the bytes for generated random.
- * @param num buffer length
+ *
+ * @param buf
+ * the bytes for generated random.
+ * @param num
+ * buffer length
* @return 1 on success, 0 otherwise.
*/
public static native int RAND_bytes(ByteBuffer buf, int num);
@@ -220,71 +203,58 @@ class OpenSslNativeJna {
/**
* Releases all functional references.
*
- * @param e engine reference.
+ * @param e
+ * engine reference.
* @return 0 on success, 1 otherwise.
*/
public static native int ENGINE_finish(PointerByReference e);
/**
* Frees the structural reference
- * @param e engine reference.
+ *
+ * @param e
+ * engine reference.
* @return 0 on success, 1 otherwise.
*/
public static native int ENGINE_free(PointerByReference e);
/**
- * Cleanups before program exit, it will avoid memory leaks.
- * @return 0 on success, 1 otherwise.
- */
- public static native int ENGINE_cleanup();
-
- /**
* Obtains a functional reference from an existing structural reference.
- * @param e engine reference
- * @return zero if the ENGINE was not already operational and couldn't be successfully initialised
+ *
+ * @param e
+ * engine reference
+ * @return zero if the ENGINE was not already operational and couldn't be successfully
+ * initialised
*/
public static native int ENGINE_init(PointerByReference e);
/**
* Sets the engine as the default for random number generation.
- * @param e engine reference
- * @param flags ENGINE_METHOD_RAND
+ *
+ * @param e
+ * engine reference
+ * @param flags
+ * ENGINE_METHOD_RAND
* @return zero if failed.
*/
public static native int ENGINE_set_default(PointerByReference e, int flags);
/**
* Gets engine by id
- * @param id engine id
+ *
+ * @param id
+ * engine id
* @return engine instance
*/
public static native PointerByReference ENGINE_by_id(String id);
/**
- * Initializes the engine.
+ * Retrieves version/build information about OpenSSL library.
+ *
+ * @param type
+ * type can be OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON...
+ * @return A pointer to a constant string describing the version of the OpenSSL library or
+ * giving information about the library build.
*/
- public static native void ENGINE_load_rdrand();
-
- //TODO callback multithreading
- /*public interface Id_function_cb extends Callback {
- long invoke ();
- }
-
- public interface Locking_function_cb extends Callback {
- void invoke(int mode, int n, String file, int line);
- }
-
- public static final Id_function_cb default_id_function = new Id_function_cb() {
-
- @Override
- public long invoke() {
- //id always positive
- long id = Thread.currentThread().getId();
- return id;
- }
- };
-
- int CRYPTO_num_locks();
- void CRYPTO_set_id_callback(Id_function_cb id_function);
- void CRYPTO_set_locking_callback(Locking_function_cb locking_function);*/
-}
\ No newline at end of file
+ public static native String OpenSSL_version(int type);
+}
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
index 14b9d34..da66c5c 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
@@ -53,4 +53,14 @@ public final class OpenSslJna {
return OpenSslNativeJna.INIT_ERROR;
}
+ /**
+ * Retrieves version/build information about OpenSSL library.
+ *
+ * @param type type can be OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON...
+ * @return A pointer to a constant string describing the version of the
+ * OpenSSL library or giving information about the library build.
+ */
+ static String OpenSSLVersion(int type) {
+ return OpenSslNativeJna.OpenSSLVersion(type);
+ }
}
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
index b3f4c4f..823637d 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
@@ -106,7 +106,7 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
close();
throw new RuntimeException("rdrand should be used but default is detected");
}
-
+
ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length);
int retVal = OpenSslNativeJna.RAND_bytes(buf, bytes.length);
throwOnError(retVal);
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
index 099c049..26507d7 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
@@ -20,7 +20,8 @@ package org.apache.commons.crypto.jna;
import java.nio.ByteBuffer;
-import com.sun.jna.Native;
+import com.sun.jna.Function;
+import com.sun.jna.NativeLibrary;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.PointerByReference;
@@ -35,256 +36,252 @@ class OpenSslNativeJna {
static final Throwable INIT_ERROR;
+ public static final long VERSION;
+ public static final long VERSION_1_0_X = 0x10000000;
+ public static final long VERSION_1_1_X = 0x10100000;
+
static {
- boolean ok = false;
- Throwable thrown = null;
+ NativeLibrary crypto = NativeLibrary.getInstance("crypto");
+ Function version = null;
try {
- Native.register("crypto");
- ERR_load_crypto_strings();
- ok = true;
- } catch (Exception e) {
- thrown = e;
+ version = crypto.getFunction("SSLeay");
} catch (UnsatisfiedLinkError e) {
- thrown = e;
- } finally {
- INIT_OK = ok;
- INIT_ERROR = thrown;
+ // Swallow the Error.
+ }
+
+ if (version == null) {
+ VERSION = VERSION_1_1_X;
+ } else {
+ VERSION = VERSION_1_0_X;
+ }
+
+ if (VERSION == VERSION_1_1_X) {
+ INIT_OK = OpenSsl11XNativeJna.INIT_OK;
+ } else {
+ INIT_OK = OpenSsl10XNativeJna.INIT_OK;
+ }
+
+ if (INIT_OK) {
+ INIT_ERROR = null;
+ } else if (VERSION == VERSION_1_1_X) {
+ INIT_ERROR = OpenSsl11XNativeJna.INIT_ERROR;
+ } else {
+ INIT_ERROR = OpenSsl10XNativeJna.INIT_ERROR;
+ }
+ }
+
+ public static PointerByReference ENGINE_by_id(String string) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.ENGINE_by_id(string);
+ } else {
+ return OpenSsl10XNativeJna.ENGINE_by_id(string);
}
}
- //misc
- /**
- * @return OPENSSL_VERSION_NUMBER which is a numeric release version
- * * identifier
- */
- public static native NativeLong SSLeay();
-
- /**
- * Retrieves version/build information about OpenSSL library.
- *
- * @param type type can be SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON...
- * @return A pointer to a constant string describing the version of the
- * OpenSSL library or giving information about the library build.
- */
- public static native String SSLeay_version(int type);
-
- /**
- * Registers the error strings for all libcrypto functions.
- */
- public static native void ERR_load_crypto_strings();
-
- /**
- * @return the earliest error code from the thread's error queue without
- * modifying it.
- */
- public static native NativeLong ERR_peek_error();
-
-
-
- /**
- * Generates a human-readable string representing the error code e.
- * @see <a>https://www.openssl.org/docs/manmaster/crypto/ERR_error_string.html</a>
- *
- * @param err the error code
- * @param null_ buf is NULL, the error string is placed in a static buffer
- * @return the human-readable error messages.
- */
- public static native String ERR_error_string(NativeLong err, char[] null_);
- //String ERR_lib_error_string(NativeLong err);
- //String ERR_func_error_string(NativeLong err);
-
- //en-/decryption
- /**
- * Creates a cipher context.
- *
- * @return a pointer to a newly created EVP_CIPHER_CTX for success and
- * NULL for failure.
- */
- public static native PointerByReference EVP_CIPHER_CTX_new();
-
-
- /**
- * EVP_CIPHER_CTX_init() remains as an alias for EVP_CIPHER_CTX_reset
- * @param p cipher context
- */
- public static native void EVP_CIPHER_CTX_init(PointerByReference p);
-
- /**
- * Enables or disables padding
- * @param c cipher context
- * @param pad If the pad parameter is zero then no padding is performed
- * @return always returns 1
- */
- public static native int EVP_CIPHER_CTX_set_padding(PointerByReference c, int pad);
-
- /**
- * @return an openssl AES evp cipher instance with a 128-bit key CBC mode
- */
- public static native PointerByReference EVP_aes_128_cbc();
-
- /**
- * @return an openssl AES evp cipher instance with a 128-bit key CTR mode
- */
- public static native PointerByReference EVP_aes_128_ctr();
-
- /**
- * @return an openssl AES evp cipher instance with a 192-bit key CBC mode
- */
- public static native PointerByReference EVP_aes_192_cbc();
-
- /**
- * @return an openssl AES evp cipher instance with a 192-bit key CTR mode
- */
- public static native PointerByReference EVP_aes_192_ctr();
-
- /**
- * @return an openssl AES evp cipher instance with a 256-bit key CBC mode
- */
- public static native PointerByReference EVP_aes_256_cbc();
-
- /**
- * @return an openssl AES evp cipher instance with a 256-bit key CTR mode
- */
- public static native PointerByReference EVP_aes_256_ctr();
-
- /**
- * Init a cipher.
- * @param ctx cipher context
- * @param cipher evp cipher instance
- * @param impl engine
- * @param key key
- * @param iv iv
- * @param enc 1 for encryption, 0 for decryption
- * @return 1 for success and 0 for failure.
- */
- public static native int EVP_CipherInit_ex(PointerByReference ctx, PointerByReference cipher, PointerByReference impl, byte key[], byte iv[], int enc);
-
-
- /**
- * Continues a multiple-part encryption/decryption operation.
- *
- * @param ctx cipher context
- * @param bout output byte buffer
- * @param outl output length
- * @param in input byte buffer
- * @param inl input length
- * @return 1 for success and 0 for failure.
- */
- public static native int EVP_CipherUpdate(PointerByReference ctx, ByteBuffer bout, int[] outl, ByteBuffer in, int inl);
-
- /**
- * Finishes a multiple-part operation.
- *
- * @param ctx cipher context
- * @param bout output byte buffer
- * @param outl output length
- * @return 1 for success and 0 for failure.
- */
- public static native int EVP_CipherFinal_ex(PointerByReference ctx, ByteBuffer bout, int[] outl);
-
- /**
- * Clears all information from a cipher context and free up any allocated
- * memory associate with it, including ctx itself.
- * @param c openssl evp cipher
- */
- public static native void EVP_CIPHER_CTX_free(PointerByReference c);
-
- /**
- * Clears all information from a cipher context and free up any allocated
- * * memory associate with it.
- * @param c openssl evp cipher
- */
- public static native void EVP_CIPHER_CTX_cleanup(PointerByReference c);
-
- //Random generator
- /**
- * OpenSSL uses for random number generation
- * @return pointers to the respective methods
- */
- public static native PointerByReference RAND_get_rand_method();
-
- /**
- * OpenSSL uses for random number generation.
- * @return pointers to the respective methods
- */
- public static native PointerByReference RAND_SSLeay();
-
- /**
- * Generates random data
- * @param buf the bytes for generated random.
- * @param num buffer length
- * @return 1 on success, 0 otherwise.
- */
- public static native int RAND_bytes(ByteBuffer buf, int num);
-
- /**
- * Releases all functional references.
- *
- * @param e engine reference.
- * @return 0 on success, 1 otherwise.
- */
- public static native int ENGINE_finish(PointerByReference e);
-
- /**
- * Frees the structural reference
- * @param e engine reference.
- * @return 0 on success, 1 otherwise.
- */
- public static native int ENGINE_free(PointerByReference e);
-
- /**
- * Cleanups before program exit, it will avoid memory leaks.
- * @return 0 on success, 1 otherwise.
- */
- public static native int ENGINE_cleanup();
-
- /**
- * Obtains a functional reference from an existing structural reference.
- * @param e engine reference
- * @return zero if the ENGINE was not already operational and couldn't be successfully initialised
- */
- public static native int ENGINE_init(PointerByReference e);
-
- /**
- * Sets the engine as the default for random number generation.
- * @param e engine reference
- * @param flags ENGINE_METHOD_RAND
- * @return zero if failed.
- */
- public static native int ENGINE_set_default(PointerByReference e, int flags);
-
- /**
- * Gets engine by id
- * @param id engine id
- * @return engine instance
- */
- public static native PointerByReference ENGINE_by_id(String id);
-
- /**
- * Initializes the engine.
- */
- public static native void ENGINE_load_rdrand();
-
- //TODO callback multithreading
- /*public interface Id_function_cb extends Callback {
- long invoke ();
+ public static void ENGINE_finish(PointerByReference rdrandEngine) {
+ if (VERSION == VERSION_1_1_X) {
+ OpenSsl11XNativeJna.ENGINE_finish(rdrandEngine);
+ } else {
+ OpenSsl10XNativeJna.ENGINE_finish(rdrandEngine);
+ }
+ }
+
+ public static void ENGINE_free(PointerByReference rdrandEngine) {
+ if (VERSION == VERSION_1_1_X) {
+ OpenSsl11XNativeJna.ENGINE_free(rdrandEngine);
+ } else {
+ OpenSsl10XNativeJna.ENGINE_free(rdrandEngine);
+ }
+ }
+
+ public static int ENGINE_init(PointerByReference rdrandEngine) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.ENGINE_init(rdrandEngine);
+ } else {
+ return OpenSsl10XNativeJna.ENGINE_init(rdrandEngine);
+ }
}
- public interface Locking_function_cb extends Callback {
- void invoke(int mode, int n, String file, int line);
+ public static int ENGINE_set_default(PointerByReference rdrandEngine, int eNGINE_METHOD_RAND) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.ENGINE_set_default(rdrandEngine, eNGINE_METHOD_RAND);
+ } else {
+ return OpenSsl10XNativeJna.ENGINE_set_default(rdrandEngine, eNGINE_METHOD_RAND);
+ }
}
- public static final Id_function_cb default_id_function = new Id_function_cb() {
+ public static String ERR_error_string(NativeLong err, Object object) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.ERR_error_string(err, null);
+ } else {
+ return OpenSsl10XNativeJna.ERR_error_string(err, null);
+ }
+ }
- @Override
- public long invoke() {
- //id always positive
- long id = Thread.currentThread().getId();
- return id;
+ public static NativeLong ERR_peek_error() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.ERR_peek_error();
+ } else {
+ return OpenSsl10XNativeJna.ERR_peek_error();
}
- };
+ }
+
+ public static PointerByReference EVP_aes_128_cbc() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_aes_128_cbc();
+ } else {
+ return OpenSsl10XNativeJna.EVP_aes_128_cbc();
+ }
+ }
+
+ public static PointerByReference EVP_aes_128_ctr() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_aes_128_ctr();
+ } else {
+ return OpenSsl10XNativeJna.EVP_aes_128_ctr();
+ }
+ }
+
+ public static PointerByReference EVP_aes_192_cbc() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_aes_192_cbc();
+ } else {
+ return OpenSsl10XNativeJna.EVP_aes_192_cbc();
+ }
+ }
+
+ public static PointerByReference EVP_aes_192_ctr() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_aes_192_ctr();
+ } else {
+ return OpenSsl10XNativeJna.EVP_aes_192_ctr();
+ }
+ }
+
+ public static PointerByReference EVP_aes_256_cbc() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_aes_256_cbc();
+ } else {
+ return OpenSsl10XNativeJna.EVP_aes_256_cbc();
+ }
+ }
+
+ public static PointerByReference EVP_aes_256_ctr() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_aes_256_ctr();
+ } else {
+ return OpenSsl10XNativeJna.EVP_aes_256_ctr();
+ }
+ }
- int CRYPTO_num_locks();
- void CRYPTO_set_id_callback(Id_function_cb id_function);
- void CRYPTO_set_locking_callback(Locking_function_cb locking_function);*/
+ public static void EVP_CIPHER_CTX_free(PointerByReference context) {
+ if (VERSION == VERSION_1_1_X) {
+ OpenSsl11XNativeJna.EVP_CIPHER_CTX_free(context);
+ } else {
+ OpenSsl10XNativeJna.EVP_CIPHER_CTX_free(context);
+ }
+ }
+
+ public static PointerByReference EVP_CIPHER_CTX_new() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_CIPHER_CTX_new();
+ } else {
+ return OpenSsl10XNativeJna.EVP_CIPHER_CTX_new();
+ }
+ }
+
+ public static void EVP_CIPHER_CTX_set_padding(PointerByReference context, int padding) {
+ if (VERSION == VERSION_1_1_X) {
+ OpenSsl11XNativeJna.EVP_CIPHER_CTX_set_padding(context, padding);
+ } else {
+ OpenSsl10XNativeJna.EVP_CIPHER_CTX_set_padding(context, padding);
+ }
+ }
+
+ public static int EVP_CipherFinal_ex(PointerByReference context, ByteBuffer outBuffer,
+ int[] outlen) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_CipherFinal_ex(context, outBuffer, outlen);
+ } else {
+ return OpenSsl10XNativeJna.EVP_CipherFinal_ex(context, outBuffer, outlen);
+ }
+ }
+
+ public static int EVP_CipherInit_ex(PointerByReference context, PointerByReference algo,
+ Object object, byte[] encoded, byte[] iv, int cipherMode) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_CipherInit_ex(context, algo, null, encoded, iv,
+ cipherMode);
+ } else {
+ return OpenSsl10XNativeJna.EVP_CipherInit_ex(context, algo, null, encoded, iv,
+ cipherMode);
+ }
+ }
+
+ public static int EVP_CipherUpdate(PointerByReference context, ByteBuffer outBuffer,
+ int[] outlen, ByteBuffer inBuffer, int remaining) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.EVP_CipherUpdate(context, outBuffer, outlen, inBuffer,
+ remaining);
+ } else {
+ return OpenSsl10XNativeJna.EVP_CipherUpdate(context, outBuffer, outlen, inBuffer,
+ remaining);
+ }
+ }
+
+ public static int RAND_bytes(ByteBuffer buf, int length) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.RAND_bytes(buf, length);
+ } else {
+ return OpenSsl10XNativeJna.RAND_bytes(buf, length);
+ }
+ }
+
+ public static PointerByReference RAND_get_rand_method() {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.RAND_get_rand_method();
+ } else {
+ return OpenSsl10XNativeJna.RAND_get_rand_method();
+ }
+ }
+
+ public static PointerByReference RAND_SSLeay() {
+ if (VERSION == VERSION_1_1_X) {
+ return null;
+ } else {
+ return OpenSsl10XNativeJna.RAND_SSLeay();
+ }
+ }
+
+ public static String OpenSSLVersion(int i) {
+ if (VERSION == VERSION_1_1_X) {
+ return OpenSsl11XNativeJna.OpenSSL_version(i);
+ } else {
+ return OpenSsl10XNativeJna.SSLeay_version(i);
+ }
+ }
+
+ public static void ENGINE_load_rdrand() {
+ if (VERSION == VERSION_1_1_X) {
+ return;
+ } else {
+ OpenSsl10XNativeJna.ENGINE_load_rdrand();
+ }
+ }
+
+ public static void ENGINE_cleanup() {
+ if (VERSION == VERSION_1_1_X) {
+ return;
+ } else {
+ OpenSsl10XNativeJna.ENGINE_cleanup();
+ }
+ }
+
+ public static void EVP_CIPHER_CTX_cleanup(PointerByReference context) {
+ if (VERSION == VERSION_1_1_X) {
+ return;
+ } else {
+ OpenSsl10XNativeJna.EVP_CIPHER_CTX_cleanup(context);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c b/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
index bb71638..937fc28 100644
--- a/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
+++ b/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
@@ -39,38 +39,20 @@
#include "OpenSslInfoNative.h"
#ifdef UNIX
-static unsigned long (*dlsym_SSLeay) (void);
-static char * (*dlsym_SSLeay_version) (int);
+static unsigned long (*dlsym_OpenSSL_version_num) (void);
+static const char * (*dlsym_OpenSSL_version) (int);
static void *openssl;
#endif
#ifdef WINDOWS
-typedef unsigned long (__cdecl *__dlsym_SSLeay) (void);
-static __dlsym_SSLeay dlsym_SSLeay;
-typedef char * (__cdecl *__dlsym_SSLeay_version) (int);
-static __dlsym_SSLeay dlsym_SSLeay;
-static __dlsym_SSLeay_version dlsym_SSLeay_version;
+typedef unsigned long (__cdecl *__dlsym_OpenSSL) (void);
+static __dlsym_OpenSSL dlsym_OpenSSL;
+typedef char * (__cdecl *__dlsym_OpenSSL_version) (int);
+static __dlsym_OpenSSL dlsym_OpenSSL;
+static __dlsym_OpenSSL_version dlsym_OpenSSL_version;
HMODULE openssl;
#endif
-#ifdef UNIX
-static void get_methods(JNIEnv *env, void *openssl)
-#endif
-#ifdef WINDOWS
-static void get_methods(JNIEnv *env, HMODULE openssl)
-#endif
-{
-#ifdef UNIX
- dlerror(); // Clear any existing error
- LOAD_DYNAMIC_SYMBOL(dlsym_SSLeay, env, openssl, "SSLeay");
- LOAD_DYNAMIC_SYMBOL(dlsym_SSLeay_version, env, openssl, "SSLeay_version");
-#endif
-
-#ifdef WINDOWS
- LOAD_DYNAMIC_SYMBOL(__dlsym_SSLeay, dlsym_SSLeay, env, openssl, "SSLeay");
- LOAD_DYNAMIC_SYMBOL(__dlsym_SSLeay_version, dlsym_SSLeay_version, env, openssl, "SSLeay_version");
-#endif
-}
static int load_library(JNIEnv *env)
{
char msg[100];
@@ -94,30 +76,12 @@ static int load_library(JNIEnv *env)
THROW(env, "java/lang/UnsatisfiedLinkError", msg);
return 0;
}
- get_methods(env, openssl);
+#ifdef UNIX
+ LOAD_OPENSSL_VERSION_FUNCTION(dlsym_OpenSSL_version_num, env, openssl);
+#endif
return 1;
}
-JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_SSLeayVersion
- (JNIEnv *env, jclass clazz, jint type)
-{
- if (!load_library(env)) {
- return NULL;
- }
-
- jstring answer = (*env)->NewStringUTF(env,dlsym_SSLeay_version(type));
- return answer;
-}
-
-JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_SSLeay
- (JNIEnv *env, jobject object)
-{
- if (!load_library(env)) {
- return 0;
- }
- return dlsym_SSLeay();
-}
-
JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_NativeVersion
(JNIEnv *env, jobject object)
{
@@ -135,3 +99,30 @@ JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_Nativ
{
return (*env)->NewStringUTF(env, PROJECT_NAME);
}
+
+JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_OpenSSL
+ (JNIEnv *env, jclass clazz)
+{
+ if (!load_library(env)) {
+ return 0;
+ }
+ jlong version_num = (jlong)dlsym_OpenSSL_version_num();
+ return version_num;
+}
+
+JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_OpenSSLVersion
+ (JNIEnv *env, jclass clazz, jint type)
+{
+ if (!load_library(env)) {
+ return NULL;
+ }
+ if (dlsym_OpenSSL_version_num() > VERSION_1_1_X) {
+ dlsym_OpenSSL_version = do_dlsym(env, openssl, "OpenSSL_version");
+ } else {
+ dlsym_OpenSSL_version = do_dlsym(env, openssl, "SSLeay_version");
+ }
+ jstring answer = (*env)->NewStringUTF(env,dlsym_OpenSSL_version(type));
+ return answer;
+}
+
+
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 ec9c945..25b4a06 100644
--- a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
+++ b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
@@ -32,9 +32,12 @@
#ifdef UNIX
static EVP_CIPHER_CTX * (*dlsym_EVP_CIPHER_CTX_new)(void);
static void (*dlsym_EVP_CIPHER_CTX_free)(EVP_CIPHER_CTX *);
-static void (*dlsym_EVP_CIPHER_CTX_init)(EVP_CIPHER_CTX *);
static int (*dlsym_EVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX *, int);
static int (*dlsym_EVP_CIPHER_CTX_ctrl)(EVP_CIPHER_CTX *, int, int, void *);
+static int (*dlsym_EVP_CIPHER_CTX_block_size)(EVP_CIPHER_CTX *);
+static EVP_CIPHER * (*dlsym_EVP_CIPHER_CTX_cipher)(EVP_CIPHER_CTX *);
+static unsigned long (*dlsym_EVP_CIPHER_flags)(const EVP_CIPHER *);
+static int (*dlsym_EVP_CIPHER_CTX_test_flags)(const EVP_CIPHER_CTX *, int);
static int (*dlsym_EVP_CipherInit_ex)(EVP_CIPHER_CTX *, const EVP_CIPHER *, \
ENGINE *, const unsigned char *, const unsigned char *, int);
static int (*dlsym_EVP_CipherUpdate)(EVP_CIPHER_CTX *, unsigned char *, \
@@ -49,12 +52,13 @@ 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 void *openssl;
#endif
#ifdef WINDOWS
typedef EVP_CIPHER_CTX * (__cdecl *__dlsym_EVP_CIPHER_CTX_new)(void);
typedef void (__cdecl *__dlsym_EVP_CIPHER_CTX_free)(EVP_CIPHER_CTX *);
-typedef void (__cdecl *__dlsym_EVP_CIPHER_CTX_init)(EVP_CIPHER_CTX *);
+typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_reset)(EVP_CIPHER_CTX *);
typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX *, int);
typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_ctrl)(EVP_CIPHER_CTX *, int, int, void *);
typedef int (__cdecl *__dlsym_EVP_CipherInit_ex)(EVP_CIPHER_CTX *, \
@@ -75,7 +79,7 @@ typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_gcm)(void);
typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_gcm)(void);
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_init dlsym_EVP_CIPHER_CTX_init;
+static __dlsym_EVP_CIPHER_CTX_reset dlsym_EVP_CIPHER_CTX_reset;
static __dlsym_EVP_CIPHER_CTX_set_padding dlsym_EVP_CIPHER_CTX_set_padding;
static __dlsym_EVP_CIPHER_CTX_ctrl dlsym_EVP_CIPHER_CTX_ctrl;
static __dlsym_EVP_CipherInit_ex dlsym_EVP_CipherInit_ex;
@@ -93,7 +97,7 @@ static __dlsym_EVP_aes_128_gcm dlsym_EVP_aes_128_gcm;
#endif
#ifdef UNIX
-static void loadAes(JNIEnv *env, void *openssl)
+static void loadAes(JNIEnv *env)
#endif
#ifdef WINDOWS
@@ -139,7 +143,7 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
{
char msg[1000];
#ifdef UNIX
- void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+ openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
#endif
#ifdef WINDOWS
@@ -161,22 +165,17 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
#ifdef UNIX
dlerror(); // Clear any existing error
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_new, env, openssl, \
- "EVP_CIPHER_CTX_new");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_free, env, openssl, \
- "EVP_CIPHER_CTX_free");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_init, env, openssl, \
- "EVP_CIPHER_CTX_init");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_set_padding, env, openssl, \
- "EVP_CIPHER_CTX_set_padding");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_ctrl, env, openssl, \
- "EVP_CIPHER_CTX_ctrl");
- 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_EVP_CIPHER_CTX_new, env, openssl, "EVP_CIPHER_CTX_new");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_free, env, openssl, "EVP_CIPHER_CTX_free");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_set_padding, env, openssl, "EVP_CIPHER_CTX_set_padding");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_ctrl, env, openssl, "EVP_CIPHER_CTX_ctrl");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_block_size, env, openssl, "EVP_CIPHER_CTX_block_size");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_cipher, env, openssl, "EVP_CIPHER_CTX_cipher");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_flags, env, openssl, "EVP_CIPHER_flags");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_test_flags, env, openssl, "EVP_CIPHER_CTX_test_flags");
+ 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");
#endif
#ifdef WINDOWS
@@ -184,8 +183,9 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
env, openssl, "EVP_CIPHER_CTX_new");
LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_free, dlsym_EVP_CIPHER_CTX_free, \
env, openssl, "EVP_CIPHER_CTX_free");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_init, dlsym_EVP_CIPHER_CTX_init, \
- env, openssl, "EVP_CIPHER_CTX_init");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_reset, \
+ dlsym_EVP_CIPHER_CTX_reset, env,
+ openssl, "EVP_CIPHER_CTX_reset");
LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_set_padding, \
dlsym_EVP_CIPHER_CTX_set_padding, env, \
openssl, "EVP_CIPHER_CTX_set_padding");
@@ -197,7 +197,7 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
env, openssl, "EVP_CipherFinal_ex");
#endif
- loadAes(env, openssl);
+ loadAes(env);
jthrowable jthr = (*env)->ExceptionOccurred(env);
if (jthr) {
(*env)->DeleteLocalRef(env, jthr);
@@ -209,9 +209,14 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
typedef struct EVP_CTX_Wrapper {
int initialized;
+ int encrypt; // ENCRYPT_MODE or DECRYPT_MODE
EVP_CIPHER_CTX *ctx;
} EVP_CTX_Wrapper;
+static int check_update_max_output_len(EVP_CTX_Wrapper *wrapper, int input_len, int max_output_len);
+static int check_doFinal_max_output_len(JNIEnv *env, EVP_CIPHER_CTX *context, int max_output_len);
+static int is_bad_tag(EVP_CTX_Wrapper *wrapper);
+
#define CTX_WRAPPER(addr) ((EVP_CTX_Wrapper *)(ptrdiff_t) addr)
static EVP_CTX_Wrapper * new_context_wrapper(JNIEnv *env) {
@@ -412,6 +417,7 @@ JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_init
}
// everything is OK,
+ wrapper->encrypt = mode;
wrapper->initialized = 1;
cleanup:
@@ -428,31 +434,6 @@ cleanup:
return JLONG(wrapper);
}
-// https://www.openssl.org/docs/crypto/EVP_EncryptInit.html
-static int check_update_max_output_len(EVP_CIPHER_CTX *context, int input_len,
- int max_output_len)
-{
- if (context->flags & EVP_CIPH_NO_PADDING) {
- if (max_output_len >= input_len) {
- return 1;
- }
- return 0;
- } else {
- int b = context->cipher->block_size;
- if (context->encrypt) {
- if (max_output_len >= input_len + b - 1) {
- return 1;
- }
- } else {
- if (max_output_len >= input_len + b) {
- return 1;
- }
- }
-
- return 0;
- }
-}
-
JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_update
(JNIEnv *env, jclass clazz, jlong ctx, jobject input, jint input_offset,
jint input_len, jobject output, jint output_offset, jint max_output_len)
@@ -462,7 +443,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updat
return 0;
}
- if (!check_update_max_output_len(context, input_len, max_output_len)) {
+ if (!check_update_max_output_len(CTX_WRAPPER(ctx), input_len, max_output_len)) {
THROW(env, "javax/crypto/ShortBufferException", \
"Output buffer is not sufficient.");
return 0;
@@ -495,10 +476,8 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updat
}
// when provide AAD to EVP cipher, output is NULL.
- if (output != NULL
- && !check_update_max_output_len(context, input_len, max_output_len)) {
- THROW(env, "javax/crypto/ShortBufferException", \
- "Output buffer is not sufficient.");
+ if (output != NULL && !check_update_max_output_len(CTX_WRAPPER(ctx), input_len, max_output_len)) {
+ THROW(env, "javax/crypto/ShortBufferException", "Output buffer is not sufficient.");
return 0;
}
@@ -544,7 +523,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updat
return 0;
}
- if (!check_update_max_output_len(context, input_len, max_output_len)) {
+ if (!check_update_max_output_len(CTX_WRAPPER(ctx), input_len, max_output_len)) {
THROW(env, "javax/crypto/ShortBufferException", \
"Output buffer is not sufficient.");
return 0;
@@ -572,23 +551,6 @@ cleanup:
return output_len;
}
-
-// https://www.openssl.org/docs/crypto/EVP_EncryptInit.html
-static int check_doFinal_max_output_len(EVP_CIPHER_CTX *context,
- int max_output_len)
-{
- if (context->flags & EVP_CIPH_NO_PADDING) {
- return 1;
- } else {
- int b = context->cipher->block_size;
- if (max_output_len >= b) {
- return 1;
- }
-
- return 0;
- }
-}
-
JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFinal
(JNIEnv *env, jclass clazz, jlong ctx, jobject output, jint offset,
jint max_output_len)
@@ -598,7 +560,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFin
return 0;
}
- if (!check_doFinal_max_output_len(context, max_output_len)) {
+ if (!check_doFinal_max_output_len(env, context, max_output_len)) {
THROW(env, "javax/crypto/ShortBufferException", \
"Output buffer is not sufficient.");
return 0;
@@ -613,8 +575,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFin
int output_len = 0;
if (!dlsym_EVP_CipherFinal_ex(context, output_bytes, &output_len)) {
// validate tag in GCM mode when decrypt
- if ((context->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_GCM_MODE
- && context->encrypt == DECRYPT_MODE) {
+ if (is_bad_tag(CTX_WRAPPER(ctx))) {
THROW(env, "javax/crypto/AEADBadTagException", "Tag mismatch!");
} else {
THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
@@ -633,7 +594,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFin
return 0;
}
- if (!check_doFinal_max_output_len(context, max_output_len)) {
+ if (!check_doFinal_max_output_len(env, context, max_output_len)) {
THROW(env, "javax/crypto/ShortBufferException", \
"Output buffer is not sufficient.");
return 0;
@@ -651,8 +612,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFin
if (rc == 0) {
// validate tag in GCM mode when decrypt
- if ((context->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_GCM_MODE
- && context->encrypt == DECRYPT_MODE) {
+ if (is_bad_tag(CTX_WRAPPER(ctx))) {
THROW(env, "javax/crypto/AEADBadTagException", "Tag mismatch!");
} else {
THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
@@ -716,3 +676,50 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_clean
EVP_CTX_Wrapper *wrapper = CTX_WRAPPER(ctx);
free_context_wrapper(wrapper);
}
+
+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) {
+ if (max_output_len >= input_len) {
+ return 1;
+ }
+ return 0;
+ } else {
+ int b = dlsym_EVP_CIPHER_CTX_block_size(wrapper->ctx);
+ if (wrapper->encrypt) {
+ if (max_output_len >= input_len + b - 1) {
+ return 1;
+ }
+ } else {
+ if (max_output_len >= input_len + b) {
+ return 1;
+ }
+ }
+ return 0;
+ }
+}
+
+static int check_doFinal_max_output_len(JNIEnv *env, EVP_CIPHER_CTX *context, int max_output_len)
+{
+ if (dlsym_EVP_CIPHER_CTX_test_flags(context, EVP_CIPH_NO_PADDING) == EVP_CIPH_NO_PADDING) {
+ return 1;
+ } else {
+ int b = dlsym_EVP_CIPHER_CTX_block_size(context);
+ if (max_output_len >= b) {
+ return 1;
+ }
+ return 0;
+ }
+}
+
+static int is_bad_tag(EVP_CTX_Wrapper *wrapper)
+{
+ EVP_CIPHER* ciph = dlsym_EVP_CIPHER_CTX_cipher(wrapper->ctx);
+ unsigned long flags = dlsym_EVP_CIPHER_flags(ciph);
+ if ((flags & EVP_CIPH_MODE) == EVP_CIPH_GCM_MODE && wrapper->encrypt == DECRYPT_MODE) {
+ return 1;
+ }
+ return 0;
+}
+
+
diff --git a/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
index b980b77..d0b43ef 100644
--- a/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
+++ b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
@@ -94,11 +94,30 @@ void *do_dlsym(JNIEnv *env, void *handle, const char *symbol) {
return func_ptr;
}
+static __attribute__ ((unused))
+void *do_version_dlsym(JNIEnv *env, void *handle) {
+ if (!env || !handle) {
+ THROW(env, "java/lang/InternalError", NULL);
+ return NULL;
+ }
+ void *func_ptr = dlsym(handle, "OpenSSL_version_num");
+ if (func_ptr == NULL) {
+ func_ptr = dlsym(handle, "SSLeay");
+ }
+ return func_ptr;
+}
+
/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
#define LOAD_DYNAMIC_SYMBOL(func_ptr, env, handle, symbol) \
if ((func_ptr = do_dlsym(env, handle, symbol)) == NULL) { \
return; \
}
+
+/* A macro to dlsym the appropriate OpenSSL version number function. */
+#define LOAD_OPENSSL_VERSION_FUNCTION(func_ptr, env, handle) \
+ if ((func_ptr = do_version_dlsym(env, handle)) == NULL) { \
+ THROW(env, "java/lang/Error", NULL); \
+ }
#endif
// Unix part end
@@ -195,6 +214,7 @@ static FARPROC WINAPI do_dlsym(JNIEnv *env, HMODULE handle, LPCSTR symbol) {
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/err.h>
+#include <openssl/opensslv.h>
/**
* A helper macro to convert the java 'context-handle'
@@ -224,6 +244,8 @@ static FARPROC WINAPI do_dlsym(JNIEnv *env, HMODULE handle, LPCSTR symbol) {
#define NOPADDING 0
#define PKCS5PADDING 1
+#define VERSION_1_0_X 0x10000000
+#define VERSION_1_1_X 0x10100000
#endif
diff --git a/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c b/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
index 56668cb..9f6078d 100644
--- a/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
+++ b/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
@@ -43,60 +43,51 @@
#ifdef UNIX
static void * (*dlsym_CRYPTO_malloc) (int, const char *, int);
static void (*dlsym_CRYPTO_free) (void *);
-static int (*dlsym_CRYPTO_num_locks) (void);
-static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
-static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
-static void (*dlsym_ENGINE_load_rdrand) (void);
static ENGINE * (*dlsym_ENGINE_by_id) (const char *);
static int (*dlsym_ENGINE_init) (ENGINE *);
static int (*dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
static int (*dlsym_ENGINE_finish) (ENGINE *);
static int (*dlsym_ENGINE_free) (ENGINE *);
-static void (*dlsym_ENGINE_cleanup) (void);
static int (*dlsym_RAND_bytes) (unsigned char *, int);
static unsigned long (*dlsym_ERR_get_error) (void);
+static unsigned long (*dlsym_OpenSSL_version_num)(void);
+static void *openssl;
#endif
#ifdef WINDOWS
typedef void * (__cdecl *__dlsym_CRYPTO_malloc) (int, const char *, int);
typedef void (__cdecl *__dlsym_CRYPTO_free) (void *);
-typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void);
-typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback) \
- (void (*)(int, int, char *, int));
-typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void);
typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id) (const char *);
typedef int (__cdecl *__dlsym_ENGINE_init) (ENGINE *);
typedef int (__cdecl *__dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *);
typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *);
-typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void);
typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int);
typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void);
static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc;
static __dlsym_CRYPTO_free dlsym_CRYPTO_free;
-static __dlsym_CRYPTO_num_locks dlsym_CRYPTO_num_locks;
-static __dlsym_CRYPTO_set_locking_callback dlsym_CRYPTO_set_locking_callback;
-static __dlsym_ENGINE_load_rdrand dlsym_ENGINE_load_rdrand;
static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id;
static __dlsym_ENGINE_init dlsym_ENGINE_init;
static __dlsym_ENGINE_set_default dlsym_ENGINE_set_default;
static __dlsym_ENGINE_finish dlsym_ENGINE_finish;
static __dlsym_ENGINE_free dlsym_ENGINE_free;
-static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup;
static __dlsym_RAND_bytes dlsym_RAND_bytes;
static __dlsym_ERR_get_error dlsym_ERR_get_error;
#endif
-static ENGINE * openssl_rand_init(void);
-static void openssl_rand_clean(ENGINE *eng, int clean_locks);
+static ENGINE * openssl_rand_init(JNIEnv *env);
+static void openssl_rand_clean(JNIEnv *env, ENGINE *eng, int clean_locks);
static int openssl_rand_bytes(unsigned char *buf, int num);
+static void pthreads_locking_callback(int mode, int type, char *file, int line);
+static unsigned long pthreads_thread_id(void);
+static pthread_mutex_t *lock_cs;
JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandomNative_initSR
(JNIEnv *env, jclass clazz)
{
char msg[1000];
#ifdef UNIX
- void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+ openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
#endif
#ifdef WINDOWS
@@ -120,22 +111,15 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandom
dlerror(); // Clear any existing error
LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_malloc, env, openssl, "CRYPTO_malloc");
LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_free, env, openssl, "CRYPTO_free");
- LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks");
- LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback, \
- env, openssl, "CRYPTO_set_locking_callback");
- LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env, \
- openssl, "CRYPTO_set_id_callback");
- LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env, \
- openssl, "ENGINE_load_rdrand");
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_set_default, env, \
openssl, "ENGINE_set_default");
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_cleanup, env, openssl, "ENGINE_cleanup");
LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes");
LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error");
+ LOAD_OPENSSL_VERSION_FUNCTION(dlsym_OpenSSL_version_num, env, openssl);
#endif
#ifdef WINDOWS
@@ -143,13 +127,6 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandom
env, openssl, "CRYPTO_malloc");
LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_free, dlsym_CRYPTO_free, \
env, openssl, "CRYPTO_free");
- LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_num_locks, dlsym_CRYPTO_num_locks, \
- env, openssl, "CRYPTO_num_locks");
- LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_set_locking_callback, \
- dlsym_CRYPTO_set_locking_callback, \
- env, openssl, "CRYPTO_set_locking_callback");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_load_rdrand, dlsym_ENGINE_load_rdrand, \
- env, openssl, "ENGINE_load_rdrand");
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, \
@@ -160,15 +137,13 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandom
env, openssl, "ENGINE_finish");
LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, \
env, openssl, "ENGINE_free");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_cleanup, dlsym_ENGINE_cleanup, \
- env, openssl, "ENGINE_cleanup");
LOAD_DYNAMIC_SYMBOL(__dlsym_RAND_bytes, dlsym_RAND_bytes, \
env, openssl, "RAND_bytes");
LOAD_DYNAMIC_SYMBOL(__dlsym_ERR_get_error, dlsym_ERR_get_error, \
env, openssl, "ERR_get_error");
#endif
- openssl_rand_init();
+ openssl_rand_init(env);
}
JNIEXPORT jboolean JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandomNative_nextRandBytes___3B
@@ -246,9 +221,11 @@ static void pthreads_locking_callback(int mode, int type, char *file, int line);
static unsigned long pthreads_thread_id(void);
static pthread_mutex_t *lock_cs;
-static void locks_setup(void)
+static void locks_setup(JNIEnv *env)
{
int i;
+ static int (*dlsym_CRYPTO_num_locks) (void);
+ dlsym_CRYPTO_num_locks = do_dlsym(env, openssl, "CRYPTO_num_locks");
lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * \
sizeof(pthread_mutex_t), __FILE__, __LINE__);
@@ -256,13 +233,22 @@ static void locks_setup(void)
pthread_mutex_init(&(lock_cs[i]), NULL);
}
+ static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
+ dlsym_CRYPTO_set_id_callback = do_dlsym(env, openssl, "CRYPTO_set_id_callback");
+ static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
+ dlsym_CRYPTO_set_locking_callback = do_dlsym(env, openssl, "CRYPTO_set_locking_callback");
+
dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
}
-static void locks_cleanup(void)
+static void locks_cleanup(JNIEnv *env)
{
int i;
+ static int (*dlsym_CRYPTO_num_locks) (void);
+ dlsym_CRYPTO_num_locks = do_dlsym(env, openssl, "CRYPTO_num_locks");
+ static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
+ dlsym_CRYPTO_set_locking_callback = do_dlsym(env, openssl, "CRYPTO_set_locking_callback");
dlsym_CRYPTO_set_locking_callback(NULL);
for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
@@ -294,11 +280,15 @@ static unsigned long pthreads_thread_id(void)
* If using an Intel chipset with RDRAND, the high-performance hardware
* random number generator will be used.
*/
-static ENGINE * openssl_rand_init(void)
+static ENGINE * openssl_rand_init(JNIEnv *env)
{
- locks_setup();
+ if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+ locks_setup(env);
+ static void (*dlsym_ENGINE_load_rdrand) (void);
+ dlsym_ENGINE_load_rdrand = do_dlsym(env, openssl, "ENGINE_load_rdrand");
+ dlsym_ENGINE_load_rdrand();
+ }
- dlsym_ENGINE_load_rdrand();
ENGINE *eng = dlsym_ENGINE_by_id("rdrand");
int ret = -1;
@@ -321,22 +311,28 @@ static ENGINE * openssl_rand_init(void)
} while(0);
if (ret == -1) {
- openssl_rand_clean(eng, 0);
+ openssl_rand_clean(env, eng, 0);
}
return eng;
}
-static void openssl_rand_clean(ENGINE *eng, int clean_locks)
+static void openssl_rand_clean(JNIEnv *env, ENGINE *eng, int clean_locks)
{
if (NULL != eng) {
dlsym_ENGINE_finish(eng);
dlsym_ENGINE_free(eng);
}
- dlsym_ENGINE_cleanup();
- if (clean_locks) {
- locks_cleanup();
+ if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+ static void (*dlsym_ENGINE_cleanup) (void);
+ if((dlsym_ENGINE_cleanup = do_dlsym(env, openssl, "ENGINE_cleanup")) == NULL) {
+ THROW(env, "java/lang/UnsatisfiedLinkError", "ENGINE_cleanup");
+ }
+ dlsym_ENGINE_cleanup();
+ if (clean_locks) {
+ locks_cleanup(env);
+ }
}
}
diff --git a/src/test/java/org/apache/commons/crypto/jna/OpenSslNativeJnaTest.java b/src/test/java/org/apache/commons/crypto/jna/OpenSslNativeJnaTest.java
index 28b3381..4857aea 100644
--- a/src/test/java/org/apache/commons/crypto/jna/OpenSslNativeJnaTest.java
+++ b/src/test/java/org/apache/commons/crypto/jna/OpenSslNativeJnaTest.java
@@ -25,7 +25,7 @@ public class OpenSslNativeJnaTest {
@Test
public void test() {
if (OpenSslJna.isEnabled()) {
- System.out.println("** INFO: JNA is using: " + OpenSslNativeJna.SSLeay_version(0));
+ System.out.println("** INFO: JNA is using: " + OpenSslJna.OpenSSLVersion(0));
} else {
System.out.println("** WARN: JNA could not be enabled: " + OpenSslJna.initialisationError().getMessage());
}