You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2016/06/30 16:31:08 UTC
[2/2] commons-crypto git commit: [CRYPTO-94] Consistently camel-case
type names: OpenSsl* (native and more)
[CRYPTO-94] Consistently camel-case type names: OpenSsl* (native and
more)
Project: http://git-wip-us.apache.org/repos/asf/commons-crypto/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-crypto/commit/4a19325f
Tree: http://git-wip-us.apache.org/repos/asf/commons-crypto/tree/4a19325f
Diff: http://git-wip-us.apache.org/repos/asf/commons-crypto/diff/4a19325f
Branch: refs/heads/master
Commit: 4a19325fdffef571cadd05000e8a2e9c376cd6af
Parents: 859bdaa
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Jun 30 09:31:02 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Jun 30 09:31:02 2016 -0700
----------------------------------------------------------------------
Makefile | 14 +-
.../apache/commons/crypto/cipher/OpenSsl.java | 16 +-
.../commons/crypto/cipher/OpenSslNative.java | 128 +++++
.../commons/crypto/cipher/OpensslNative.java | 128 -----
.../apache/commons/crypto/jna/OpenSslJna.java | 35 ++
.../commons/crypto/jna/OpenSslJnaCipher.java | 36 +-
.../crypto/jna/OpenSslJnaCryptoRandom.java | 24 +-
.../apache/commons/crypto/jna/OpensslJna.java | 35 --
.../commons/crypto/jna/OpensslNativeJna.java | 2 +-
.../crypto/random/OpenSslCryptoRandom.java | 6 +-
.../random/OpenSslCryptoRandomNative.java | 48 ++
.../random/OpensslCryptoRandomNative.java | 48 --
.../commons/crypto/cipher/OpenSslNative.c | 500 +++++++++++++++++++
.../commons/crypto/cipher/OpensslNative.c | 500 -------------------
.../crypto/random/OpenSslCryptoRandomNative.c | 340 +++++++++++++
.../crypto/random/OpensslCryptoRandomNative.c | 340 -------------
.../crypto/cipher/AbstractCipherTest.java | 4 +-
.../crypto/cipher/OpenSslCipherTest.java | 175 +++++++
.../crypto/cipher/OpensslCipherTest.java | 175 -------
.../crypto/jna/OpenSslJnaCipherTest.java | 45 ++
.../crypto/jna/OpenSslJnaCryptoRandomTest.java | 47 ++
.../crypto/jna/OpensslJnaCipherTest.java | 45 --
.../crypto/jna/OpensslJnaCryptoRandomTest.java | 47 --
23 files changed, 1369 insertions(+), 1369 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/Makefile
----------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index 69ce464..8d7ecdf 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ include Makefile.common
MVN:=mvn
COMMONS_CRYPTO_OUT:=$(TARGET)/$(commons-crypto)-$(os_arch)
-COMMONS_CRYPTO_OBJ:=$(addprefix $(COMMONS_CRYPTO_OUT)/,OpensslCryptoRandom.o OpensslNative.o)
+COMMONS_CRYPTO_OBJ:=$(addprefix $(COMMONS_CRYPTO_OUT)/,OpensslCryptoRandom.o OpenSslNative.o)
ifeq ($(OS_NAME),SunOS)
TAR:= gtar
@@ -33,17 +33,17 @@ NATIVE_DLL:=$(NATIVE_TARGET_DIR)/$(LIBNAME)
all: $(NATIVE_DLL)
-$(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpensslNative.h: $(TARGET)/classes/org/apache/commons/crypto/cipher/OpensslNative.class
- $(JAVAH) -force -classpath $(TARGET)/jni-classes:$(TARGET)/classes -o $@ org.apache.commons.crypto.cipher.OpensslNative
+$(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpenSslNative.h: $(TARGET)/classes/org/apache/commons/crypto/cipher/OpenSslNative.class
+ $(JAVAH) -force -classpath $(TARGET)/jni-classes:$(TARGET)/classes -o $@ org.apache.commons.crypto.cipher.OpenSslNative
-$(TARGET)/jni-classes/org/apache/commons/crypto/random/OpensslCryptoRandomNative.h: $(TARGET)/classes/org/apache/commons/crypto/random/OpensslCryptoRandomNative.class
- $(JAVAH) -force -classpath $(TARGET)/jni-classes:$(TARGET)/classes -o $@ org.apache.commons.crypto.random.OpensslCryptoRandomNative
+$(TARGET)/jni-classes/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.h: $(TARGET)/classes/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.class
+ $(JAVAH) -force -classpath $(TARGET)/jni-classes:$(TARGET)/classes -o $@ org.apache.commons.crypto.random.OpenSslCryptoRandomNative
-$(COMMONS_CRYPTO_OUT)/OpensslNative.o : $(SRC_NATIVE)/org/apache/commons/crypto/cipher/OpensslNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpensslNative.h
+$(COMMONS_CRYPTO_OUT)/OpenSslNative.o : $(SRC_NATIVE)/org/apache/commons/crypto/cipher/OpenSslNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpenSslNative.h
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $< -o $@
-$(COMMONS_CRYPTO_OUT)/OpensslCryptoRandom.o : $(SRC_NATIVE)/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/random/OpensslCryptoRandomNative.h
+$(COMMONS_CRYPTO_OUT)/OpensslCryptoRandom.o : $(SRC_NATIVE)/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.h
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $< -o $@
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
index 6c72ea5..231c3bc 100644
--- a/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
+++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
@@ -92,7 +92,7 @@ final class OpenSsl {
String loadingFailure = null;
try {
if (Crypto.isNativeCodeLoaded()) {
- OpensslNative.initIDs();
+ OpenSslNative.initIDs();
}
} catch (Exception t) {
loadingFailure = t.getMessage();
@@ -142,7 +142,7 @@ final class OpenSsl {
int algorithmMode = AlgorithmMode.get(transform.algorithm,
transform.mode);
int padding = Padding.get(transform.padding);
- long context = OpensslNative.initContext(algorithmMode, padding);
+ long context = OpenSslNative.initContext(algorithmMode, padding);
return new OpenSsl(context, algorithmMode, padding);
}
@@ -205,7 +205,7 @@ final class OpenSsl {
* @param iv crypto iv
*/
public void init(int mode, byte[] key, byte[] iv) {
- context = OpensslNative
+ context = OpenSslNative
.init(context, mode, algorithm, padding, key, iv);
}
@@ -242,7 +242,7 @@ final class OpenSsl {
checkState();
Utils.checkArgument(input.isDirect() && output.isDirect(),
"Direct buffers are required.");
- int len = OpensslNative.update(context, input, input.position(),
+ int len = OpenSslNative.update(context, input, input.position(),
input.remaining(), output, output.position(),
output.remaining());
input.position(input.limit());
@@ -266,7 +266,7 @@ final class OpenSsl {
public int update(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset) throws ShortBufferException {
checkState();
- return OpensslNative.updateByteArray(context, input, inputOffset,
+ return OpenSslNative.updateByteArray(context, input, inputOffset,
inputLen, output, outputOffset, output.length - outputOffset);
}
@@ -313,7 +313,7 @@ final class OpenSsl {
IllegalBlockSizeException, BadPaddingException {
checkState();
Utils.checkArgument(output.isDirect(), "Direct buffer is required.");
- int len = OpensslNative.doFinal(context, output, output.position(),
+ int len = OpenSslNative.doFinal(context, output, output.position(),
output.remaining());
output.position(output.position() + len);
return len;
@@ -341,14 +341,14 @@ final class OpenSsl {
throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
checkState();
- return OpensslNative.doFinalByteArray(context, output, outputOffset,
+ return OpenSslNative.doFinalByteArray(context, output, outputOffset,
output.length - outputOffset);
}
/** Forcibly clean the context. */
public void clean() {
if (context != 0) {
- OpensslNative.clean(context);
+ OpenSslNative.clean(context);
context = 0;
}
}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java
new file mode 100644
index 0000000..c73be17
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java
@@ -0,0 +1,128 @@
+/**
+ * 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.cipher;
+
+import java.nio.ByteBuffer;
+
+/**
+ * JNI interface of {@link OpenSsl} implementation. The native method in this
+ * class is defined in OpenSslNative.h (generated by javah).
+ */
+class OpenSslNative {
+
+ /**
+ * The private constructor of {@link OpenSslNative}.
+ */
+ private OpenSslNative() {
+ }
+
+ /**
+ * Declares a native method to initialize JNI field and method IDs.
+ */
+ public native static void initIDs();
+
+ /**
+ * Declares a native method to initialize the cipher context.
+ *
+ * @param algorithm The algorithm name of cipher
+ * @param padding The padding name of cipher
+ * @return the context address of cipher
+ */
+ public native static long initContext(int algorithm, int padding);
+
+ /**
+ * Declares a native method to initialize the cipher context.
+ *
+ * @param context The cipher context address
+ * @param mode ENCRYPT_MODE or DECRYPT_MODE
+ * @param alg Algorithm Mode of OpenSsl
+ * @param padding the padding mode of OpenSsl cipher
+ * @param key crypto key
+ * @param iv crypto iv
+ * @return the context address of cipher
+ */
+ public native static long init(long context, int mode, int alg,
+ int padding, byte[] key, byte[] iv);
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data is
+ * encrypted or decrypted, depending on how this cipher was initialized.
+ *
+ * @param context The cipher context address
+ * @param input The input byte buffer
+ * @param inputOffset The offset in input where the input starts
+ * @param inputLength The input length
+ * @param output The byte buffer for the result
+ * @param outputOffset The offset in output where the result is stored
+ * @param maxOutputLength The maximum length for output
+ * @return The number of bytes stored in output
+ */
+ public native static int update(long context, ByteBuffer input,
+ int inputOffset, int inputLength, ByteBuffer output,
+ int outputOffset, int maxOutputLength);
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data is
+ * encrypted or decrypted, depending on how this cipher was initialized.
+ *
+ * @param context The cipher context address
+ * @param input The input byte array
+ * @param inputOffset The offset in input where the input starts
+ * @param inputLength The input length
+ * @param output The byte array for the result
+ * @param outputOffset The offset in output where the result is stored
+ * @param maxOutputLength The maximum length for output
+ * @return The number of bytes stored in output
+ */
+ public native static int updateByteArray(long context, byte[] input,
+ int inputOffset, int inputLength, byte[] output, int outputOffset,
+ int maxOutputLength);
+
+ /**
+ * Finishes a multiple-part operation. The data is encrypted or decrypted,
+ * depending on how this cipher was initialized.
+ *
+ * @param context The cipher context address
+ * @param output The byte buffer for the result
+ * @param offset The offset in output where the result is stored
+ * @param maxOutputLength The maximum length for output
+ * @return The number of bytes stored in output
+ */
+ public native static int doFinal(long context, ByteBuffer output,
+ int offset, int maxOutputLength);
+
+ /**
+ * Finishes a multiple-part operation. The data is encrypted or decrypted,
+ * depending on how this cipher was initialized.
+ *
+ * @param context The cipher context address
+ * @param output The byte array for the result
+ * @param offset The offset in output where the result is stored
+ * @param maxOutputLength The maximum length for output
+ * @return The number of bytes stored in output
+ */
+ public native static int doFinalByteArray(long context, byte[] output,
+ int offset, int maxOutputLength);
+
+ /**
+ * Cleans the context at native.
+ *
+ * @param context The cipher context address
+ */
+ public native static void clean(long context);
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java b/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java
deleted file mode 100644
index 9bac6dd..0000000
--- a/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * 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.cipher;
-
-import java.nio.ByteBuffer;
-
-/**
- * JNI interface of {@link OpenSsl} implementation. The native method in this
- * class is defined in OpensslNative.h (generated by javah).
- */
-class OpensslNative {
-
- /**
- * The private constructor of {@link OpensslNative}.
- */
- private OpensslNative() {
- }
-
- /**
- * Declares a native method to initialize JNI field and method IDs.
- */
- public native static void initIDs();
-
- /**
- * Declares a native method to initialize the cipher context.
- *
- * @param algorithm The algorithm name of cipher
- * @param padding The padding name of cipher
- * @return the context address of cipher
- */
- public native static long initContext(int algorithm, int padding);
-
- /**
- * Declares a native method to initialize the cipher context.
- *
- * @param context The cipher context address
- * @param mode ENCRYPT_MODE or DECRYPT_MODE
- * @param alg Algorithm Mode of OpenSsl
- * @param padding the padding mode of OpenSsl cipher
- * @param key crypto key
- * @param iv crypto iv
- * @return the context address of cipher
- */
- public native static long init(long context, int mode, int alg,
- int padding, byte[] key, byte[] iv);
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data is
- * encrypted or decrypted, depending on how this cipher was initialized.
- *
- * @param context The cipher context address
- * @param input The input byte buffer
- * @param inputOffset The offset in input where the input starts
- * @param inputLength The input length
- * @param output The byte buffer for the result
- * @param outputOffset The offset in output where the result is stored
- * @param maxOutputLength The maximum length for output
- * @return The number of bytes stored in output
- */
- public native static int update(long context, ByteBuffer input,
- int inputOffset, int inputLength, ByteBuffer output,
- int outputOffset, int maxOutputLength);
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data is
- * encrypted or decrypted, depending on how this cipher was initialized.
- *
- * @param context The cipher context address
- * @param input The input byte array
- * @param inputOffset The offset in input where the input starts
- * @param inputLength The input length
- * @param output The byte array for the result
- * @param outputOffset The offset in output where the result is stored
- * @param maxOutputLength The maximum length for output
- * @return The number of bytes stored in output
- */
- public native static int updateByteArray(long context, byte[] input,
- int inputOffset, int inputLength, byte[] output, int outputOffset,
- int maxOutputLength);
-
- /**
- * Finishes a multiple-part operation. The data is encrypted or decrypted,
- * depending on how this cipher was initialized.
- *
- * @param context The cipher context address
- * @param output The byte buffer for the result
- * @param offset The offset in output where the result is stored
- * @param maxOutputLength The maximum length for output
- * @return The number of bytes stored in output
- */
- public native static int doFinal(long context, ByteBuffer output,
- int offset, int maxOutputLength);
-
- /**
- * Finishes a multiple-part operation. The data is encrypted or decrypted,
- * depending on how this cipher was initialized.
- *
- * @param context The cipher context address
- * @param output The byte array for the result
- * @param offset The offset in output where the result is stored
- * @param maxOutputLength The maximum length for output
- * @return The number of bytes stored in output
- */
- public native static int doFinalByteArray(long context, byte[] output,
- int offset, int maxOutputLength);
-
- /**
- * Cleans the context at native.
- *
- * @param context The cipher context address
- */
- public native static void clean(long context);
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
new file mode 100644
index 0000000..cfdff2e
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
@@ -0,0 +1,35 @@
+/*
+ * 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 org.apache.commons.crypto.cipher.CryptoCipher;
+import org.apache.commons.crypto.random.CryptoRandom;
+
+/**
+ * Public class to give access to the package protected class objects
+ */
+public final class OpenSslJna {
+
+ public static Class<? extends CryptoCipher> getCipherClass() {
+ return OpenSslJnaCipher.class;
+ }
+
+ public static Class<? extends CryptoRandom> getRandomClass() {
+ return OpenSslJnaCryptoRandom.class;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
index adef3cf..7b0b978 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
@@ -71,7 +71,7 @@ class OpenSslJnaCipher implements CryptoCipher {
}
padding = Padding.get(transform.padding);
- context = OpensslNativeJna.EVP_CIPHER_CTX_new();
+ context = OpenSslNativeJna.EVP_CIPHER_CTX_new();
}
@@ -89,9 +89,9 @@ class OpenSslJnaCipher implements CryptoCipher {
throws InvalidKeyException, InvalidAlgorithmParameterException {
Utils.checkNotNull(key);
Utils.checkNotNull(params);
- int cipherMode = OpensslNativeJna.OOSL_JNA_DECRYPT_MODE;
+ int cipherMode = OpenSslNativeJna.OOSL_JNA_DECRYPT_MODE;
if (mode == Cipher.ENCRYPT_MODE) {
- cipherMode = OpensslNativeJna.OOSL_JNA_ENCRYPT_MODE;
+ cipherMode = OpenSslNativeJna.OOSL_JNA_ENCRYPT_MODE;
}
byte[] iv;
if (params instanceof IvParameterSpec) {
@@ -104,24 +104,24 @@ class OpenSslJnaCipher implements CryptoCipher {
if(algMode == AlgorithmMode.AES_CBC) {
switch(key.getEncoded().length) {
- case 16: algo = OpensslNativeJna.EVP_aes_128_cbc(); break;
- case 24: algo = OpensslNativeJna.EVP_aes_192_cbc(); break;
- case 32: algo = OpensslNativeJna.EVP_aes_256_cbc(); break;
+ case 16: algo = OpenSslNativeJna.EVP_aes_128_cbc(); break;
+ case 24: algo = OpenSslNativeJna.EVP_aes_192_cbc(); break;
+ case 32: algo = OpenSslNativeJna.EVP_aes_256_cbc(); break;
default: throw new InvalidKeyException("keysize unsupported ("+key.getEncoded().length+")");
}
} else {
switch(key.getEncoded().length) {
- case 16: algo = OpensslNativeJna.EVP_aes_128_ctr(); break;
- case 24: algo = OpensslNativeJna.EVP_aes_192_ctr(); break;
- case 32: algo = OpensslNativeJna.EVP_aes_256_ctr(); break;
+ case 16: algo = OpenSslNativeJna.EVP_aes_128_ctr(); break;
+ case 24: algo = OpenSslNativeJna.EVP_aes_192_ctr(); break;
+ case 32: algo = OpenSslNativeJna.EVP_aes_256_ctr(); break;
default: throw new InvalidKeyException("keysize unsupported ("+key.getEncoded().length+")");
}
}
- int retVal = OpensslNativeJna.EVP_CipherInit_ex(context, algo, null, key.getEncoded(), iv, cipherMode);
+ int retVal = OpenSslNativeJna.EVP_CipherInit_ex(context, algo, null, key.getEncoded(), iv, cipherMode);
throwOnError(retVal);
- OpensslNativeJna.EVP_CIPHER_CTX_set_padding(context, padding);
+ OpenSslNativeJna.EVP_CIPHER_CTX_set_padding(context, padding);
}
/**
@@ -138,7 +138,7 @@ class OpenSslJnaCipher implements CryptoCipher {
public int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
throws ShortBufferException {
int[] outlen = new int[1];
- int retVal = OpensslNativeJna.EVP_CipherUpdate(context, outBuffer, outlen, inBuffer, inBuffer.remaining());
+ int retVal = OpenSslNativeJna.EVP_CipherUpdate(context, outBuffer, outlen, inBuffer, inBuffer.remaining());
throwOnError(retVal);
int len = outlen[0];
inBuffer.position(inBuffer.limit());
@@ -191,7 +191,7 @@ class OpenSslJnaCipher implements CryptoCipher {
BadPaddingException {
int uptLen = update(inBuffer, outBuffer);
int[] outlen = new int[1];
- int retVal = OpensslNativeJna.EVP_CipherFinal_ex(context, outBuffer, outlen);
+ int retVal = OpenSslNativeJna.EVP_CipherFinal_ex(context, outBuffer, outlen);
throwOnError(retVal);
int len = uptLen + outlen[0];
outBuffer.position(outBuffer.position() + outlen[0]);
@@ -234,18 +234,18 @@ class OpenSslJnaCipher implements CryptoCipher {
@Override
public void close() {
if(context != null) {
- OpensslNativeJna.EVP_CIPHER_CTX_cleanup(context);
- OpensslNativeJna.EVP_CIPHER_CTX_free(context);
+ OpenSslNativeJna.EVP_CIPHER_CTX_cleanup(context);
+ OpenSslNativeJna.EVP_CIPHER_CTX_free(context);
}
}
private void throwOnError(int retVal) {
if(retVal != 1) {
- NativeLong err = OpensslNativeJna.ERR_peek_error();
- String errdesc = OpensslNativeJna.ERR_error_string(err, null);
+ NativeLong err = OpenSslNativeJna.ERR_peek_error();
+ String errdesc = OpenSslNativeJna.ERR_error_string(err, null);
if(context != null) {
- OpensslNativeJna.EVP_CIPHER_CTX_cleanup(context);
+ OpenSslNativeJna.EVP_CIPHER_CTX_cleanup(context);
}
throw new RuntimeException("return code "+retVal+" from openssl. Err code is "+err+": "+errdesc);
}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
----------------------------------------------------------------------
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 1f4e971..7ab0b48 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
@@ -62,14 +62,14 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
boolean rdrandLoaded = false;
try {
- OpensslNativeJna.ENGINE_load_rdrand();
- rdrandEngine = OpensslNativeJna.ENGINE_by_id("rdrand");
+ OpenSslNativeJna.ENGINE_load_rdrand();
+ rdrandEngine = OpenSslNativeJna.ENGINE_by_id("rdrand");
int ENGINE_METHOD_RAND = 0x0008;
if(rdrandEngine != null) {
- int rc = OpensslNativeJna.ENGINE_init(rdrandEngine);
+ int rc = OpenSslNativeJna.ENGINE_init(rdrandEngine);
if(rc != 0) {
- int rc2 = OpensslNativeJna.ENGINE_set_default(rdrandEngine, ENGINE_METHOD_RAND);
+ int rc2 = OpenSslNativeJna.ENGINE_set_default(rdrandEngine, ENGINE_METHOD_RAND);
if(rc2 != 0) {
rdrandLoaded = true;
}
@@ -99,13 +99,13 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
//this method is synchronized for now
//to support multithreading https://wiki.openssl.org/index.php/Manual:Threads(3) needs to be done
- if(rdrandEnabled && OpensslNativeJna.RAND_get_rand_method().equals(OpensslNativeJna.RAND_SSLeay())) {
+ if(rdrandEnabled && OpenSslNativeJna.RAND_get_rand_method().equals(OpenSslNativeJna.RAND_SSLeay())) {
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);
+ int retVal = OpenSslNativeJna.RAND_bytes(buf, bytes.length);
throwOnError(retVal);
buf.rewind();
buf.get(bytes,0, bytes.length);
@@ -155,18 +155,18 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
@Override
public void close() {
closeRdrandEngine();
- OpensslNativeJna.ENGINE_cleanup();
+ OpenSslNativeJna.ENGINE_cleanup();
//cleanup locks
- //OpensslNativeJna.CRYPTO_set_locking_callback(null);
+ //OpenSslNativeJna.CRYPTO_set_locking_callback(null);
//LOCK.unlock();
}
private void closeRdrandEngine() {
if(rdrandEngine != null) {
- OpensslNativeJna.ENGINE_finish(rdrandEngine);
- OpensslNativeJna.ENGINE_free(rdrandEngine);
+ OpenSslNativeJna.ENGINE_finish(rdrandEngine);
+ OpenSslNativeJna.ENGINE_free(rdrandEngine);
}
}
@@ -181,8 +181,8 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
private void throwOnError(int retVal) {
if(retVal != 1) {
- NativeLong err = OpensslNativeJna.ERR_peek_error();
- String errdesc = OpensslNativeJna.ERR_error_string(err, null);
+ NativeLong err = OpenSslNativeJna.ERR_peek_error();
+ String errdesc = OpenSslNativeJna.ERR_error_string(err, null);
close();
throw new RuntimeException("return code "+retVal+" from openssl. Err code is "+err+": "+errdesc);
}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpensslJna.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpensslJna.java b/src/main/java/org/apache/commons/crypto/jna/OpensslJna.java
deleted file mode 100644
index 2d255ab..0000000
--- a/src/main/java/org/apache/commons/crypto/jna/OpensslJna.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 org.apache.commons.crypto.cipher.CryptoCipher;
-import org.apache.commons.crypto.random.CryptoRandom;
-
-/**
- * Public class to give access to the package protected class objects
- */
-public final class OpensslJna {
-
- public static Class<? extends CryptoCipher> getCipherClass() {
- return OpenSslJnaCipher.class;
- }
-
- public static Class<? extends CryptoRandom> getRandomClass() {
- return OpenSslJnaCryptoRandom.class;
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpensslNativeJna.java
----------------------------------------------------------------------
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 5ffa25b..6adddb2 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpensslNativeJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpensslNativeJna.java
@@ -24,7 +24,7 @@ import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.PointerByReference;
-class OpensslNativeJna {
+class OpenSslNativeJna {
static final int OPENSSL_INIT_ENGINE_RDRAND = 0x00000200;
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java
index 15a85ab..b02139e 100644
--- a/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java
+++ b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java
@@ -52,7 +52,7 @@ class OpenSslCryptoRandom extends Random implements CryptoRandom {
boolean opensslLoaded = false;
if (Crypto.isNativeCodeLoaded()) {
try {
- OpensslCryptoRandomNative.initSR();
+ OpenSslCryptoRandomNative.initSR();
opensslLoaded = true;
} catch (Exception t) {// NOPMD
}
@@ -82,7 +82,7 @@ class OpenSslCryptoRandom extends Random implements CryptoRandom {
public OpenSslCryptoRandom(Properties props)
throws NoSuchAlgorithmException {
//fallback needs to be initialized here in any case cause even if
- //nativeEnabled is true OpensslCryptoRandomNative.nextRandBytes may fail
+ //nativeEnabled is true OpenSslCryptoRandomNative.nextRandBytes may fail
fallback = new JavaCryptoRandom(props);
}
@@ -93,7 +93,7 @@ class OpenSslCryptoRandom extends Random implements CryptoRandom {
*/
@Override
public void nextBytes(byte[] bytes) {
- if (!nativeEnabled || !OpensslCryptoRandomNative.nextRandBytes(bytes)) {
+ if (!nativeEnabled || !OpenSslCryptoRandomNative.nextRandBytes(bytes)) {
fallback.nextBytes(bytes);
}
}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.java b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.java
new file mode 100644
index 0000000..84b92a6
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.java
@@ -0,0 +1,48 @@
+/**
+ * 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.random;
+
+/**
+ * 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
+ * src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
+ */
+class OpenSslCryptoRandomNative {
+ /**
+ * The private constructor of {@link OpenSslCryptoRandomNative}.
+ */
+ private OpenSslCryptoRandomNative() {
+ }
+
+ /**
+ * Declares a native method to initialize SR.
+ */
+ public native static void initSR();
+
+ /**
+ * Judges whether use {@link OpenSslCryptoRandomNative} to generate the
+ * user-specified number of random bits.
+ *
+ * @param bytes the array to be filled in with random bytes.
+ * @return true if use {@link OpenSslCryptoRandomNative} to generate the
+ * user-specified number of random bits.
+ */
+ public native static boolean nextRandBytes(byte[] bytes);
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/random/OpensslCryptoRandomNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OpensslCryptoRandomNative.java b/src/main/java/org/apache/commons/crypto/random/OpensslCryptoRandomNative.java
deleted file mode 100644
index 8c305e0..0000000
--- a/src/main/java/org/apache/commons/crypto/random/OpensslCryptoRandomNative.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * 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.random;
-
-/**
- * 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
- * src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c
- */
-class OpensslCryptoRandomNative {
- /**
- * The private constructor of {@link OpensslCryptoRandomNative}.
- */
- private OpensslCryptoRandomNative() {
- }
-
- /**
- * Declares a native method to initialize SR.
- */
- public native static void initSR();
-
- /**
- * Judges whether use {@link OpensslCryptoRandomNative} to generate the
- * user-specified number of random bits.
- *
- * @param bytes the array to be filled in with random bytes.
- * @return true if use {@link OpensslCryptoRandomNative} to generate the
- * user-specified number of random bits.
- */
- public native static boolean nextRandBytes(byte[] bytes);
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
new file mode 100644
index 0000000..fd35f61
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
@@ -0,0 +1,500 @@
+/**
+ * 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.
+ */
+
+#include "org_apache_commons_crypto.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// export the native interfaces
+#ifdef JNIEXPORT
+#undef JNIEXPORT
+#endif
+#define JNIEXPORT __attribute__((__visibility__("default")))
+#include "OpenSslNative.h"
+
+#ifdef UNIX
+static EVP_CIPHER_CTX * (*dlsym_EVP_CIPHER_CTX_new)(void);
+static void (*dlsym_EVP_CIPHER_CTX_free)(EVP_CIPHER_CTX *);
+static int (*dlsym_EVP_CIPHER_CTX_cleanup)(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_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 *, \
+ int *, const unsigned char *, int);
+static int (*dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *, unsigned char *, int *);
+static EVP_CIPHER * (*dlsym_EVP_aes_256_ctr)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_192_ctr)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_128_ctr)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_256_cbc)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_192_cbc)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_128_cbc)(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 int (__cdecl *__dlsym_EVP_CIPHER_CTX_cleanup)(EVP_CIPHER_CTX *);
+typedef void (__cdecl *__dlsym_EVP_CIPHER_CTX_init)(EVP_CIPHER_CTX *);
+typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX *, int);
+typedef int (__cdecl *__dlsym_EVP_CipherInit_ex)(EVP_CIPHER_CTX *, \
+ const EVP_CIPHER *, ENGINE *, const unsigned char *, \
+ const unsigned char *, int);
+typedef int (__cdecl *__dlsym_EVP_CipherUpdate)(EVP_CIPHER_CTX *, \
+ unsigned char *, int *, const unsigned char *, int);
+typedef int (__cdecl *__dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *, \
+ unsigned char *, int *);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_ctr)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_ctr)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_ctr)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_cbc)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_cbc)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_cbc)(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_cleanup dlsym_EVP_CIPHER_CTX_cleanup;
+static __dlsym_EVP_CIPHER_CTX_init dlsym_EVP_CIPHER_CTX_init;
+static __dlsym_EVP_CIPHER_CTX_set_padding dlsym_EVP_CIPHER_CTX_set_padding;
+static __dlsym_EVP_CipherInit_ex dlsym_EVP_CipherInit_ex;
+static __dlsym_EVP_CipherUpdate dlsym_EVP_CipherUpdate;
+static __dlsym_EVP_CipherFinal_ex dlsym_EVP_CipherFinal_ex;
+static __dlsym_EVP_aes_256_ctr dlsym_EVP_aes_256_ctr;
+static __dlsym_EVP_aes_192_ctr dlsym_EVP_aes_192_ctr;
+static __dlsym_EVP_aes_128_ctr dlsym_EVP_aes_128_ctr;
+static __dlsym_EVP_aes_256_cbc dlsym_EVP_aes_256_cbc;
+static __dlsym_EVP_aes_192_cbc dlsym_EVP_aes_192_cbc;
+static __dlsym_EVP_aes_128_cbc dlsym_EVP_aes_128_cbc;
+static HMODULE openssl;
+#endif
+
+static void loadAes(JNIEnv *env)
+{
+#ifdef UNIX
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_256_ctr, env, openssl, "EVP_aes_256_ctr");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_192_ctr, env, openssl, "EVP_aes_192_ctr");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_128_ctr, env, openssl, "EVP_aes_128_ctr");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_256_cbc, env, openssl, "EVP_aes_256_cbc");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_192_cbc, env, openssl, "EVP_aes_192_cbc");
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_128_cbc, env, openssl, "EVP_aes_128_cbc");
+#endif
+
+#ifdef WINDOWS
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_256_ctr, dlsym_EVP_aes_256_ctr, \
+ env, openssl, "EVP_aes_256_ctr");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_192_ctr, dlsym_EVP_aes_192_ctr, \
+ env, openssl, "EVP_aes_192_ctr");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_128_ctr, dlsym_EVP_aes_128_ctr, \
+ env, openssl, "EVP_aes_128_ctr");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_256_cbc, dlsym_EVP_aes_256_cbc, \
+ env, openssl, "EVP_aes_256_cbc");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_192_cbc, dlsym_EVP_aes_192_cbc, \
+ env, openssl, "EVP_aes_192_cbc");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_128_cbc, dlsym_EVP_aes_128_cbc, \
+ env, openssl, "EVP_aes_128_cbc");
+#endif
+}
+
+JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ char msg[1000];
+#ifdef UNIX
+ openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+#endif
+
+#ifdef WINDOWS
+ openssl = LoadLibrary(COMMONS_CRYPTO_OPENSSL_LIBRARY);
+#endif
+
+ if (!openssl) {
+ snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY, \
+ dlerror());
+ THROW(env, "java/lang/UnsatisfiedLinkError", msg);
+ return;
+ }
+
+#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_cleanup, env, openssl, \
+ "EVP_CIPHER_CTX_cleanup");
+ 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_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
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_new, dlsym_EVP_CIPHER_CTX_new, \
+ 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_cleanup, \
+ dlsym_EVP_CIPHER_CTX_cleanup, env,
+ openssl, "EVP_CIPHER_CTX_cleanup");
+ 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_set_padding, \
+ dlsym_EVP_CIPHER_CTX_set_padding, env, \
+ openssl, "EVP_CIPHER_CTX_set_padding");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherInit_ex, dlsym_EVP_CipherInit_ex, \
+ env, openssl, "EVP_CipherInit_ex");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherUpdate, dlsym_EVP_CipherUpdate, \
+ env, openssl, "EVP_CipherUpdate");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherFinal_ex, dlsym_EVP_CipherFinal_ex, \
+ env, openssl, "EVP_CipherFinal_ex");
+#endif
+
+ loadAes(env);
+ jthrowable jthr = (*env)->ExceptionOccurred(env);
+ if (jthr) {
+ (*env)->DeleteLocalRef(env, jthr);
+ THROW(env, "java/lang/UnsatisfiedLinkError", \
+ "Cannot find AES-CTR support, is your version of Openssl new enough?");
+ return;
+ }
+}
+
+JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initContext
+ (JNIEnv *env, jclass clazz, jint alg, jint padding)
+{
+ if (alg != AES_CTR && alg != AES_CBC) {
+ THROW(env, "java/security/NoSuchAlgorithmException", NULL);
+ return (jlong)0;
+ }
+ if (!(alg == AES_CTR && padding == NOPADDING)
+ && !(alg == AES_CBC && (padding == NOPADDING|| padding == PKCS5PADDING))) {
+ THROW(env, "javax/crypto/NoSuchPaddingException", NULL);
+ return (jlong)0;
+ }
+
+ if (dlsym_EVP_aes_256_ctr == NULL ||
+ dlsym_EVP_aes_192_ctr == NULL || dlsym_EVP_aes_128_ctr == NULL) {
+ THROW(env, "java/security/NoSuchAlgorithmException", \
+ "Doesn't support AES CTR.");
+ return (jlong)0;
+ }
+
+ if (dlsym_EVP_aes_256_cbc == NULL ||
+ dlsym_EVP_aes_192_cbc == NULL || dlsym_EVP_aes_128_cbc == NULL) {
+ THROW(env, "java/security/NoSuchAlgorithmException", \
+ "Doesn't support AES CBC.");
+ return (jlong)0;
+ }
+
+ // Create and initialize a EVP_CIPHER_CTX
+ EVP_CIPHER_CTX *context = dlsym_EVP_CIPHER_CTX_new();
+ if (!context) {
+ THROW(env, "java/lang/OutOfMemoryError", NULL);
+ return (jlong)0;
+ }
+
+ return JLONG(context);
+}
+
+// Only supports AES-CTR and AES-CBC currently
+static EVP_CIPHER * getEvpCipher(int alg, int keyLen)
+{
+ EVP_CIPHER *cipher = NULL;
+ if (alg == AES_CTR) {
+ if (keyLen == KEY_LENGTH_256) {
+ cipher = dlsym_EVP_aes_256_ctr();
+ } else if (keyLen == KEY_LENGTH_192) {
+ cipher = dlsym_EVP_aes_192_ctr();
+ } else if (keyLen == KEY_LENGTH_128) {
+ cipher = dlsym_EVP_aes_128_ctr();
+ }
+ } else if (alg == AES_CBC) {
+ if (keyLen == KEY_LENGTH_256) {
+ cipher = dlsym_EVP_aes_256_cbc();
+ } else if (keyLen == KEY_LENGTH_192) {
+ cipher = dlsym_EVP_aes_192_cbc();
+ } else if (keyLen == KEY_LENGTH_128) {
+ cipher = dlsym_EVP_aes_128_cbc();
+ }
+ }
+ return cipher;
+}
+
+JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_init
+ (JNIEnv *env, jclass clazz, jlong ctx, jint mode, jint alg, jint padding,
+ jbyteArray key, jbyteArray iv)
+{
+ jlong result = 0L;
+ EVP_CIPHER_CTX *context = CONTEXT(ctx);
+
+ jbyte *jKey = NULL;
+ jbyte *jIv = NULL;
+ int jKeyLen = (*env)->GetArrayLength(env, key);
+ int jIvLen = (*env)->GetArrayLength(env, iv);
+ if (jKeyLen != KEY_LENGTH_128 && jKeyLen != KEY_LENGTH_192
+ && jKeyLen != KEY_LENGTH_256) {
+ char str[64] = {0};
+ snprintf(str, sizeof(str), "Invalid AES key length: %d bytes", jKeyLen);
+ THROW(env, "java/security/InvalidKeyException", str);
+ goto cleanup;
+ }
+ if (jIvLen != IV_LENGTH) {
+ THROW(env, "java/security/InvalidAlgorithmParameterException", "Wrong IV length: must be 16 bytes long");
+ goto cleanup;
+ }
+
+ if (context == 0) {
+ // Create and initialize a EVP_CIPHER_CTX
+ context = dlsym_EVP_CIPHER_CTX_new();
+ if (!context) {
+ THROW(env, "java/lang/OutOfMemoryError", NULL);
+ return (jlong)0;
+ }
+ }
+
+ jKey = (*env)->GetByteArrayElements(env, key, NULL);
+ if (jKey == NULL) {
+ THROW(env, "java/lang/InternalError", "Cannot get bytes array for key.");
+ goto cleanup;
+ }
+ jIv = (*env)->GetByteArrayElements(env, iv, NULL);
+ if (jIv == NULL) {
+ THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
+ goto cleanup;
+ }
+
+ if (!(alg == AES_CTR || alg == AES_CBC)) {
+ THROW(env, "java/security/NoSuchAlgorithmException", "The algorithm is not supported.");
+ goto cleanup;
+ }
+
+ int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen), \
+ NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
+ if (rc == 0) {
+ THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
+ goto cleanup;
+ }
+
+ if (padding == NOPADDING) {
+ dlsym_EVP_CIPHER_CTX_set_padding(context, 0);
+ } else if (padding == PKCS5PADDING) {
+ dlsym_EVP_CIPHER_CTX_set_padding(context, 1);
+ }
+
+ // everything is OK,
+ result = JLONG(context);
+
+cleanup:
+ if (result == 0 && context != NULL) {
+ if (CONTEXT(ctx) != NULL) {
+ dlsym_EVP_CIPHER_CTX_cleanup(context);
+ } else {
+ dlsym_EVP_CIPHER_CTX_free(context);
+ }
+ }
+ if (jKey != NULL) {
+ (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
+ }
+ if (jIv != NULL) {
+ (*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
+ }
+
+ return result;
+}
+
+// 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)
+{
+ EVP_CIPHER_CTX *context = CONTEXT(ctx);
+ if (!check_update_max_output_len(context, input_len, max_output_len)) {
+ THROW(env, "javax/crypto/ShortBufferException", \
+ "Output buffer is not sufficient.");
+ return 0;
+ }
+ unsigned char *input_bytes = (*env)->GetDirectBufferAddress(env, input);
+ unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
+ if (input_bytes == NULL || output_bytes == NULL) {
+ THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
+ return 0;
+ }
+ input_bytes = input_bytes + input_offset;
+ output_bytes = output_bytes + output_offset;
+
+ int output_len = 0;
+ if (!dlsym_EVP_CipherUpdate(context, output_bytes, &output_len, \
+ input_bytes, input_len)) {
+ dlsym_EVP_CIPHER_CTX_cleanup(context);
+ THROW(env, "java/lang/InternalError", "Error in EVP_CipherUpdate.");
+ return 0;
+ }
+ return output_len;
+}
+
+JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updateByteArray
+ (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray input, jint input_offset,
+ jint input_len, jbyteArray output, jint output_offset, jint max_output_len)
+{
+ EVP_CIPHER_CTX *context = CONTEXT(ctx);
+ if (!check_update_max_output_len(context, input_len, max_output_len)) {
+ THROW(env, "javax/crypto/ShortBufferException", \
+ "Output buffer is not sufficient.");
+ return 0;
+ }
+ unsigned char *input_bytes = NULL;
+ unsigned char *output_bytes = NULL;
+ int output_len = 0;
+
+ input_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, input, 0);
+ output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
+ if (input_bytes == NULL || output_bytes == NULL) {
+ THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
+ goto cleanup;
+ }
+
+ int rc = dlsym_EVP_CipherUpdate(context, output_bytes + output_offset, &output_len, \
+ input_bytes + input_offset, input_len);
+ if (rc == 0) {
+ dlsym_EVP_CIPHER_CTX_cleanup(context);
+ THROW(env, "java/lang/InternalError", "Error in EVP_CipherUpdate.");
+ output_len = 0;
+ }
+
+cleanup:
+ if (input_bytes != NULL) {
+ (*env)->ReleaseByteArrayElements(env, input, (jbyte *) input_bytes, 0);
+ }
+ if (output_bytes != NULL) {
+ (*env)->ReleaseByteArrayElements(env, output, (jbyte *) output_bytes, 0);
+ }
+
+ 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)
+{
+ EVP_CIPHER_CTX *context = CONTEXT(ctx);
+ if (!check_doFinal_max_output_len(context, max_output_len)) {
+ THROW(env, "javax/crypto/ShortBufferException", \
+ "Output buffer is not sufficient.");
+ return 0;
+ }
+ unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
+ if (output_bytes == NULL) {
+ THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
+ return 0;
+ }
+ output_bytes = output_bytes + offset;
+
+ int output_len = 0;
+ if (!dlsym_EVP_CipherFinal_ex(context, output_bytes, &output_len)) {
+ dlsym_EVP_CIPHER_CTX_cleanup(context);
+ THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
+ return 0;
+ }
+ return output_len;
+}
+
+JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFinalByteArray
+ (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray output, jint offset,
+ jint max_output_len)
+{
+ EVP_CIPHER_CTX *context = CONTEXT(ctx);
+ if (!check_doFinal_max_output_len(context, max_output_len)) {
+ THROW(env, "javax/crypto/ShortBufferException", \
+ "Output buffer is not sufficient.");
+ return 0;
+ }
+ unsigned char *output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
+ if (output_bytes == NULL) {
+ THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
+ return 0;
+ }
+
+ int output_len = 0;
+ int rc = dlsym_EVP_CipherFinal_ex(context, output_bytes + offset, &output_len);
+
+ (*env)->ReleaseByteArrayElements(env, output, (jbyte *) output_bytes, 0);
+
+ if (rc == 0) {
+ dlsym_EVP_CIPHER_CTX_cleanup(context);
+ THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
+ return 0;
+ }
+ return output_len;
+}
+
+JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_clean
+ (JNIEnv *env, jclass clazz, jlong ctx)
+{
+ EVP_CIPHER_CTX *context = CONTEXT(ctx);
+ if (context) {
+ dlsym_EVP_CIPHER_CTX_free(context);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c b/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c
deleted file mode 100644
index f409011..0000000
--- a/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/**
- * 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.
- */
-
-#include "org_apache_commons_crypto.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// export the native interfaces
-#ifdef JNIEXPORT
-#undef JNIEXPORT
-#endif
-#define JNIEXPORT __attribute__((__visibility__("default")))
-#include "OpensslNative.h"
-
-#ifdef UNIX
-static EVP_CIPHER_CTX * (*dlsym_EVP_CIPHER_CTX_new)(void);
-static void (*dlsym_EVP_CIPHER_CTX_free)(EVP_CIPHER_CTX *);
-static int (*dlsym_EVP_CIPHER_CTX_cleanup)(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_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 *, \
- int *, const unsigned char *, int);
-static int (*dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *, unsigned char *, int *);
-static EVP_CIPHER * (*dlsym_EVP_aes_256_ctr)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_192_ctr)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_128_ctr)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_256_cbc)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_192_cbc)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_128_cbc)(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 int (__cdecl *__dlsym_EVP_CIPHER_CTX_cleanup)(EVP_CIPHER_CTX *);
-typedef void (__cdecl *__dlsym_EVP_CIPHER_CTX_init)(EVP_CIPHER_CTX *);
-typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX *, int);
-typedef int (__cdecl *__dlsym_EVP_CipherInit_ex)(EVP_CIPHER_CTX *, \
- const EVP_CIPHER *, ENGINE *, const unsigned char *, \
- const unsigned char *, int);
-typedef int (__cdecl *__dlsym_EVP_CipherUpdate)(EVP_CIPHER_CTX *, \
- unsigned char *, int *, const unsigned char *, int);
-typedef int (__cdecl *__dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *, \
- unsigned char *, int *);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_ctr)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_ctr)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_ctr)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_cbc)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_cbc)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_cbc)(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_cleanup dlsym_EVP_CIPHER_CTX_cleanup;
-static __dlsym_EVP_CIPHER_CTX_init dlsym_EVP_CIPHER_CTX_init;
-static __dlsym_EVP_CIPHER_CTX_set_padding dlsym_EVP_CIPHER_CTX_set_padding;
-static __dlsym_EVP_CipherInit_ex dlsym_EVP_CipherInit_ex;
-static __dlsym_EVP_CipherUpdate dlsym_EVP_CipherUpdate;
-static __dlsym_EVP_CipherFinal_ex dlsym_EVP_CipherFinal_ex;
-static __dlsym_EVP_aes_256_ctr dlsym_EVP_aes_256_ctr;
-static __dlsym_EVP_aes_192_ctr dlsym_EVP_aes_192_ctr;
-static __dlsym_EVP_aes_128_ctr dlsym_EVP_aes_128_ctr;
-static __dlsym_EVP_aes_256_cbc dlsym_EVP_aes_256_cbc;
-static __dlsym_EVP_aes_192_cbc dlsym_EVP_aes_192_cbc;
-static __dlsym_EVP_aes_128_cbc dlsym_EVP_aes_128_cbc;
-static HMODULE openssl;
-#endif
-
-static void loadAes(JNIEnv *env)
-{
-#ifdef UNIX
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_256_ctr, env, openssl, "EVP_aes_256_ctr");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_192_ctr, env, openssl, "EVP_aes_192_ctr");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_128_ctr, env, openssl, "EVP_aes_128_ctr");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_256_cbc, env, openssl, "EVP_aes_256_cbc");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_192_cbc, env, openssl, "EVP_aes_192_cbc");
- LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_128_cbc, env, openssl, "EVP_aes_128_cbc");
-#endif
-
-#ifdef WINDOWS
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_256_ctr, dlsym_EVP_aes_256_ctr, \
- env, openssl, "EVP_aes_256_ctr");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_192_ctr, dlsym_EVP_aes_192_ctr, \
- env, openssl, "EVP_aes_192_ctr");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_128_ctr, dlsym_EVP_aes_128_ctr, \
- env, openssl, "EVP_aes_128_ctr");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_256_cbc, dlsym_EVP_aes_256_cbc, \
- env, openssl, "EVP_aes_256_cbc");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_192_cbc, dlsym_EVP_aes_192_cbc, \
- env, openssl, "EVP_aes_192_cbc");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_128_cbc, dlsym_EVP_aes_128_cbc, \
- env, openssl, "EVP_aes_128_cbc");
-#endif
-}
-
-JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_initIDs
- (JNIEnv *env, jclass clazz)
-{
- char msg[1000];
-#ifdef UNIX
- openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
-#endif
-
-#ifdef WINDOWS
- openssl = LoadLibrary(COMMONS_CRYPTO_OPENSSL_LIBRARY);
-#endif
-
- if (!openssl) {
- snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY, \
- dlerror());
- THROW(env, "java/lang/UnsatisfiedLinkError", msg);
- return;
- }
-
-#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_cleanup, env, openssl, \
- "EVP_CIPHER_CTX_cleanup");
- 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_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
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_new, dlsym_EVP_CIPHER_CTX_new, \
- 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_cleanup, \
- dlsym_EVP_CIPHER_CTX_cleanup, env,
- openssl, "EVP_CIPHER_CTX_cleanup");
- 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_set_padding, \
- dlsym_EVP_CIPHER_CTX_set_padding, env, \
- openssl, "EVP_CIPHER_CTX_set_padding");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherInit_ex, dlsym_EVP_CipherInit_ex, \
- env, openssl, "EVP_CipherInit_ex");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherUpdate, dlsym_EVP_CipherUpdate, \
- env, openssl, "EVP_CipherUpdate");
- LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherFinal_ex, dlsym_EVP_CipherFinal_ex, \
- env, openssl, "EVP_CipherFinal_ex");
-#endif
-
- loadAes(env);
- jthrowable jthr = (*env)->ExceptionOccurred(env);
- if (jthr) {
- (*env)->DeleteLocalRef(env, jthr);
- THROW(env, "java/lang/UnsatisfiedLinkError", \
- "Cannot find AES-CTR support, is your version of Openssl new enough?");
- return;
- }
-}
-
-JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_initContext
- (JNIEnv *env, jclass clazz, jint alg, jint padding)
-{
- if (alg != AES_CTR && alg != AES_CBC) {
- THROW(env, "java/security/NoSuchAlgorithmException", NULL);
- return (jlong)0;
- }
- if (!(alg == AES_CTR && padding == NOPADDING)
- && !(alg == AES_CBC && (padding == NOPADDING|| padding == PKCS5PADDING))) {
- THROW(env, "javax/crypto/NoSuchPaddingException", NULL);
- return (jlong)0;
- }
-
- if (dlsym_EVP_aes_256_ctr == NULL ||
- dlsym_EVP_aes_192_ctr == NULL || dlsym_EVP_aes_128_ctr == NULL) {
- THROW(env, "java/security/NoSuchAlgorithmException", \
- "Doesn't support AES CTR.");
- return (jlong)0;
- }
-
- if (dlsym_EVP_aes_256_cbc == NULL ||
- dlsym_EVP_aes_192_cbc == NULL || dlsym_EVP_aes_128_cbc == NULL) {
- THROW(env, "java/security/NoSuchAlgorithmException", \
- "Doesn't support AES CBC.");
- return (jlong)0;
- }
-
- // Create and initialize a EVP_CIPHER_CTX
- EVP_CIPHER_CTX *context = dlsym_EVP_CIPHER_CTX_new();
- if (!context) {
- THROW(env, "java/lang/OutOfMemoryError", NULL);
- return (jlong)0;
- }
-
- return JLONG(context);
-}
-
-// Only supports AES-CTR and AES-CBC currently
-static EVP_CIPHER * getEvpCipher(int alg, int keyLen)
-{
- EVP_CIPHER *cipher = NULL;
- if (alg == AES_CTR) {
- if (keyLen == KEY_LENGTH_256) {
- cipher = dlsym_EVP_aes_256_ctr();
- } else if (keyLen == KEY_LENGTH_192) {
- cipher = dlsym_EVP_aes_192_ctr();
- } else if (keyLen == KEY_LENGTH_128) {
- cipher = dlsym_EVP_aes_128_ctr();
- }
- } else if (alg == AES_CBC) {
- if (keyLen == KEY_LENGTH_256) {
- cipher = dlsym_EVP_aes_256_cbc();
- } else if (keyLen == KEY_LENGTH_192) {
- cipher = dlsym_EVP_aes_192_cbc();
- } else if (keyLen == KEY_LENGTH_128) {
- cipher = dlsym_EVP_aes_128_cbc();
- }
- }
- return cipher;
-}
-
-JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_init
- (JNIEnv *env, jclass clazz, jlong ctx, jint mode, jint alg, jint padding,
- jbyteArray key, jbyteArray iv)
-{
- jlong result = 0L;
- EVP_CIPHER_CTX *context = CONTEXT(ctx);
-
- jbyte *jKey = NULL;
- jbyte *jIv = NULL;
- int jKeyLen = (*env)->GetArrayLength(env, key);
- int jIvLen = (*env)->GetArrayLength(env, iv);
- if (jKeyLen != KEY_LENGTH_128 && jKeyLen != KEY_LENGTH_192
- && jKeyLen != KEY_LENGTH_256) {
- char str[64] = {0};
- snprintf(str, sizeof(str), "Invalid AES key length: %d bytes", jKeyLen);
- THROW(env, "java/security/InvalidKeyException", str);
- goto cleanup;
- }
- if (jIvLen != IV_LENGTH) {
- THROW(env, "java/security/InvalidAlgorithmParameterException", "Wrong IV length: must be 16 bytes long");
- goto cleanup;
- }
-
- if (context == 0) {
- // Create and initialize a EVP_CIPHER_CTX
- context = dlsym_EVP_CIPHER_CTX_new();
- if (!context) {
- THROW(env, "java/lang/OutOfMemoryError", NULL);
- return (jlong)0;
- }
- }
-
- jKey = (*env)->GetByteArrayElements(env, key, NULL);
- if (jKey == NULL) {
- THROW(env, "java/lang/InternalError", "Cannot get bytes array for key.");
- goto cleanup;
- }
- jIv = (*env)->GetByteArrayElements(env, iv, NULL);
- if (jIv == NULL) {
- THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
- goto cleanup;
- }
-
- if (!(alg == AES_CTR || alg == AES_CBC)) {
- THROW(env, "java/security/NoSuchAlgorithmException", "The algorithm is not supported.");
- goto cleanup;
- }
-
- int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen), \
- NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
- if (rc == 0) {
- THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
- goto cleanup;
- }
-
- if (padding == NOPADDING) {
- dlsym_EVP_CIPHER_CTX_set_padding(context, 0);
- } else if (padding == PKCS5PADDING) {
- dlsym_EVP_CIPHER_CTX_set_padding(context, 1);
- }
-
- // everything is OK,
- result = JLONG(context);
-
-cleanup:
- if (result == 0 && context != NULL) {
- if (CONTEXT(ctx) != NULL) {
- dlsym_EVP_CIPHER_CTX_cleanup(context);
- } else {
- dlsym_EVP_CIPHER_CTX_free(context);
- }
- }
- if (jKey != NULL) {
- (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
- }
- if (jIv != NULL) {
- (*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
- }
-
- return result;
-}
-
-// 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)
-{
- EVP_CIPHER_CTX *context = CONTEXT(ctx);
- if (!check_update_max_output_len(context, input_len, max_output_len)) {
- THROW(env, "javax/crypto/ShortBufferException", \
- "Output buffer is not sufficient.");
- return 0;
- }
- unsigned char *input_bytes = (*env)->GetDirectBufferAddress(env, input);
- unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
- if (input_bytes == NULL || output_bytes == NULL) {
- THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
- return 0;
- }
- input_bytes = input_bytes + input_offset;
- output_bytes = output_bytes + output_offset;
-
- int output_len = 0;
- if (!dlsym_EVP_CipherUpdate(context, output_bytes, &output_len, \
- input_bytes, input_len)) {
- dlsym_EVP_CIPHER_CTX_cleanup(context);
- THROW(env, "java/lang/InternalError", "Error in EVP_CipherUpdate.");
- return 0;
- }
- return output_len;
-}
-
-JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_updateByteArray
- (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray input, jint input_offset,
- jint input_len, jbyteArray output, jint output_offset, jint max_output_len)
-{
- EVP_CIPHER_CTX *context = CONTEXT(ctx);
- if (!check_update_max_output_len(context, input_len, max_output_len)) {
- THROW(env, "javax/crypto/ShortBufferException", \
- "Output buffer is not sufficient.");
- return 0;
- }
- unsigned char *input_bytes = NULL;
- unsigned char *output_bytes = NULL;
- int output_len = 0;
-
- input_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, input, 0);
- output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
- if (input_bytes == NULL || output_bytes == NULL) {
- THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
- goto cleanup;
- }
-
- int rc = dlsym_EVP_CipherUpdate(context, output_bytes + output_offset, &output_len, \
- input_bytes + input_offset, input_len);
- if (rc == 0) {
- dlsym_EVP_CIPHER_CTX_cleanup(context);
- THROW(env, "java/lang/InternalError", "Error in EVP_CipherUpdate.");
- output_len = 0;
- }
-
-cleanup:
- if (input_bytes != NULL) {
- (*env)->ReleaseByteArrayElements(env, input, (jbyte *) input_bytes, 0);
- }
- if (output_bytes != NULL) {
- (*env)->ReleaseByteArrayElements(env, output, (jbyte *) output_bytes, 0);
- }
-
- 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)
-{
- EVP_CIPHER_CTX *context = CONTEXT(ctx);
- if (!check_doFinal_max_output_len(context, max_output_len)) {
- THROW(env, "javax/crypto/ShortBufferException", \
- "Output buffer is not sufficient.");
- return 0;
- }
- unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
- if (output_bytes == NULL) {
- THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
- return 0;
- }
- output_bytes = output_bytes + offset;
-
- int output_len = 0;
- if (!dlsym_EVP_CipherFinal_ex(context, output_bytes, &output_len)) {
- dlsym_EVP_CIPHER_CTX_cleanup(context);
- THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
- return 0;
- }
- return output_len;
-}
-
-JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_doFinalByteArray
- (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray output, jint offset,
- jint max_output_len)
-{
- EVP_CIPHER_CTX *context = CONTEXT(ctx);
- if (!check_doFinal_max_output_len(context, max_output_len)) {
- THROW(env, "javax/crypto/ShortBufferException", \
- "Output buffer is not sufficient.");
- return 0;
- }
- unsigned char *output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
- if (output_bytes == NULL) {
- THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
- return 0;
- }
-
- int output_len = 0;
- int rc = dlsym_EVP_CipherFinal_ex(context, output_bytes + offset, &output_len);
-
- (*env)->ReleaseByteArrayElements(env, output, (jbyte *) output_bytes, 0);
-
- if (rc == 0) {
- dlsym_EVP_CIPHER_CTX_cleanup(context);
- THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
- return 0;
- }
- return output_len;
-}
-
-JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_clean
- (JNIEnv *env, jclass clazz, jlong ctx)
-{
- EVP_CIPHER_CTX *context = CONTEXT(ctx);
- if (context) {
- dlsym_EVP_CIPHER_CTX_free(context);
- }
-}