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 <s...@apache.org>
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
+}

Reply via email to