This is an automated email from the ASF dual-hosted git repository.
sebb 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 aed0ea47 Add JNA support for OpenSSL3
aed0ea47 is described below
commit aed0ea47a3591a6a1dd5e46b55aa8cb29f8dc8dc
Author: Sebb <[email protected]>
AuthorDate: Sat Nov 4 12:32:33 2023 +0000
Add JNA support for OpenSSL3
JNI support TBC
---
.../commons/crypto/jna/OpenSsl30XNativeJna.java | 413 +++++++++++++++++++++
.../commons/crypto/jna/OpenSslNativeJna.java | 16 +-
2 files changed, 422 insertions(+), 7 deletions(-)
diff --git
a/src/main/java/org/apache/commons/crypto/jna/OpenSsl30XNativeJna.java
b/src/main/java/org/apache/commons/crypto/jna/OpenSsl30XNativeJna.java
new file mode 100644
index 00000000..ff2aeaf4
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSsl30XNativeJna.java
@@ -0,0 +1,413 @@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.crypto.jna;
+
+import java.nio.ByteBuffer;
+
+import org.apache.commons.crypto.Crypto;
+
+import com.sun.jna.Native;
+import com.sun.jna.NativeLong;
+import com.sun.jna.ptr.PointerByReference;
+
+// Currently this is the same as OpenSsl11XNativeJna
+// This may change if additional methods need to be added
+final class OpenSsl30XNativeJna implements OpenSslInterfaceNativeJna {
+
+ static final boolean INIT_OK;
+
+ static final Throwable INIT_ERROR;
+
+ static {
+ boolean ok = false;
+ Throwable thrown = null;
+ try {
+ final String libName = System.getProperty(Crypto.CONF_PREFIX +
OpenSslNativeJna.class.getSimpleName(), "crypto");
+ OpenSslJna.debug("Native.register('%s')", libName);
+ Native.register(libName);
+ ok = true;
+ } catch (final Exception | UnsatisfiedLinkError e) {
+ thrown = e;
+ } finally {
+ INIT_OK = ok;
+ INIT_ERROR = thrown;
+ }
+ }
+
+ // Try to keep methods aligned across versions
+
+ /**
+ * Gets engine by id
+ *
+ * @param id
+ * engine id
+ * @return engine instance
+ */
+ public static native PointerByReference ENGINE_by_id(String id);
+
+ /**
+ * 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);
+
+ /**
+ * 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
+ * initialized
+ */
+ 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);
+
+ /**
+ * Generates a human-readable string representing the error code e.
+ *
+ * @see <a
href="https://www.openssl.org/docs/man3.1.0/man3/ERR_error_string.html">ERR_error_string</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_);
+
+ /**
+ * @return the earliest error code from the thread's error queue without
modifying it.
+ */
+ public static native NativeLong ERR_peek_error();
+
+ /**
+ * @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();
+
+ /**
+ * 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);
+
+ /**
+ * 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();
+
+ /**
+ * Clears all information from a cipher context and free up any allocated
* memory associate
+ * with it.
+ *
+ * @param c
+ * openssl evp cipher
+ */
+
+ /**
+ * 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);
+
+ /**
+ * 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);
+
+ // ENGINE API: https://www.openssl.org/docs/man1.1.1/man3/ENGINE_add.html
+ // (The above page includes all the ENGINE functions used below)
+
+ /**
+ * 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);
+
+ /**
+ * Retrieves version/build information about OpenSSL library.
+ *
+ * @see <a
href="https://www.openssl.org/docs/man1.1.1/man3/OpenSSL_version.html">OpenSSL_version</a>
+ * @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 String OpenSSL_version(int type);
+
+ /**
+ * 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);
+
+ // Random generator
+ /**
+ * OpenSSL uses for random number generation
+ *
+ * @return pointers to the respective methods
+ */
+ public static native PointerByReference RAND_get_rand_method();
+
+ @Override
+ public PointerByReference _ENGINE_by_id(final String string) {
+ return ENGINE_by_id(string);
+ }
+
+ @Override
+ public int _ENGINE_cleanup() {
+ return 0; // Not available
+ }
+
+ @Override
+ public int _ENGINE_finish(final PointerByReference rdrandEngine) {
+ return ENGINE_finish(rdrandEngine);
+ }
+
+ @Override
+ public int _ENGINE_free(final PointerByReference rdrandEngine) {
+ return ENGINE_free(rdrandEngine);
+ }
+
+ @Override
+ public int _ENGINE_init(final PointerByReference rdrandEngine) {
+ return ENGINE_init(rdrandEngine);
+ }
+
+ @Override
+ public void _ENGINE_load_rdrand() {
+ // Not available
+ }
+
+ @Override
+ public int _ENGINE_set_default(final PointerByReference rdrandEngine,
final int flags) {
+ return ENGINE_set_default(rdrandEngine, flags);
+ }
+
+ @Override
+ public String _ERR_error_string(final NativeLong err, final char[] buff) {
+ return ERR_error_string(err, buff);
+ }
+
+ @Override
+ public NativeLong _ERR_peek_error() {
+ return ERR_peek_error();
+ }
+
+ @Override
+ public PointerByReference _EVP_aes_128_cbc() {
+ return EVP_aes_128_cbc();
+ }
+
+ @Override
+ public PointerByReference _EVP_aes_128_ctr() {
+ return EVP_aes_128_ctr();
+ }
+
+ @Override
+ public PointerByReference _EVP_aes_192_cbc() {
+ return EVP_aes_192_cbc();
+ }
+
+ @Override
+ public PointerByReference _EVP_aes_192_ctr() {
+ return EVP_aes_192_ctr();
+ }
+
+ @Override
+ public PointerByReference _EVP_aes_256_cbc() {
+ return EVP_aes_256_cbc();
+ }
+
+ @Override
+ public PointerByReference _EVP_aes_256_ctr() {
+ return EVP_aes_256_ctr();
+ }
+
+ @Override
+ public void _EVP_CIPHER_CTX_cleanup(final PointerByReference context) {
+ // Not available
+ }
+
+ @Override
+ public void _EVP_CIPHER_CTX_free(final PointerByReference context) {
+ EVP_CIPHER_CTX_free(context);
+ }
+
+ @Override
+ public PointerByReference _EVP_CIPHER_CTX_new() {
+ return EVP_CIPHER_CTX_new();
+ }
+
+ @Override
+ public int _EVP_CIPHER_CTX_set_padding(final PointerByReference context,
final int padding) {
+ return EVP_CIPHER_CTX_set_padding(context, padding);
+ }
+
+ @Override
+ public int _EVP_CipherFinal_ex(final PointerByReference context, final
ByteBuffer outBuffer, final int[] outlen) {
+ return EVP_CipherFinal_ex(context, outBuffer, outlen);
+ }
+
+ @Override
+ public int _EVP_CipherInit_ex(final PointerByReference context, final
PointerByReference algo, final PointerByReference impl, final byte[] encoded,
+ final byte[] iv, final int cipherMode) {
+ return EVP_CipherInit_ex(context, algo, impl, encoded, iv, cipherMode);
+ }
+
+ @Override
+ public int _EVP_CipherUpdate(final PointerByReference context, final
ByteBuffer outBuffer, final int[] outlen, final ByteBuffer inBuffer,
+ final int remaining) {
+ return EVP_CipherUpdate(context, outBuffer, outlen, inBuffer,
remaining);
+ }
+
+ @Override
+ public Throwable _INIT_ERROR() {
+ return INIT_ERROR;
+ }
+
+ @Override
+ public boolean _INIT_OK() {
+ return INIT_OK;
+ }
+
+ @Override
+ public String _OpenSSL_version(final int i) {
+ return OpenSSL_version(i);
+ }
+
+ @Override
+ public int _RAND_bytes(final ByteBuffer buf, final int length) {
+ return RAND_bytes(buf, length) ;
+ }
+
+ @Override
+ public PointerByReference _RAND_get_rand_method() {
+ return RAND_get_rand_method();
+ }
+
+ @Override
+ public PointerByReference _RAND_SSLeay() {
+ return null; // Not available
+ }
+
+}
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 ccd87a6e..b8103bc2 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
@@ -48,6 +48,7 @@ final class OpenSslNativeJna {
static final long VERSION_1_1_X = 0x10100000;
static final long VERSION_2_0_X = 0x20000000;
static final long VERSION_3_0_X = 0x30000000;
+ static final long VERSION_3_1_X = 0x30100000;
private static final OpenSslInterfaceNativeJna JnaImplementation;
@@ -67,9 +68,10 @@ final class OpenSslNativeJna {
// Must find one of the above two functions; else give up
VERSION = versionFunction.invokeLong(new Object[]{});
- OpenSslJna.debug(String.format("OpenSslNativeJna detected version
0x%x", VERSION));
-
VERSION_X_Y = VERSION & 0xffff0000; // keep only major.minor
+
+ OpenSslJna.debug(String.format("OpenSslNativeJna detected version 0x%x
=> 0x%x", VERSION, VERSION_X_Y));
+
if (VERSION_X_Y == VERSION_1_0_X) {
OpenSslJna.debug("Creating OpenSsl10XNativeJna");
JnaImplementation = new OpenSsl10XNativeJna();
@@ -79,10 +81,10 @@ final class OpenSslNativeJna {
} else if (VERSION_X_Y == VERSION_2_0_X) {
OpenSslJna.debug("Creating OpenSsl20XNativeJna");
JnaImplementation = new OpenSsl20XNativeJna();
-// } else if (VERSION_X_Y == VERSION_3_0_X) {
-// OpenSslJna.debug("Creating OpenSsl30XNativeJna");
-// JnaImplementation = new OpenSsl30XNativeJna();
- } else {
+ } else if (VERSION_X_Y == VERSION_3_0_X || VERSION_X_Y ==
VERSION_3_1_X) { // assume these are the same
+ OpenSslJna.debug("Creating OpenSsl30XNativeJna");
+ JnaImplementation = new OpenSsl30XNativeJna();
+ } else {
// TODO: Throw error?
OpenSslJna.debug("Creating OpenSsl10XNativeJna");
JnaImplementation = new OpenSsl10XNativeJna();
@@ -204,4 +206,4 @@ final class OpenSslNativeJna {
private OpenSslNativeJna() {
}
-}
\ No newline at end of file
+}