You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by xu...@apache.org on 2016/04/22 07:18:29 UTC
[1/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
Repository: commons-crypto
Updated Branches:
refs/heads/master 92d129aa5 -> 4920d2729
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java b/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java
new file mode 100644
index 0000000..e48d548
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java
@@ -0,0 +1,242 @@
+/**
+ * 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.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.util.Properties;
+import java.util.Random;
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.commons.crypto.conf.ConfigurationKeys;
+import org.apache.commons.crypto.utils.ReflectionUtils;
+import org.apache.commons.crypto.utils.Utils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public abstract class AbstractCipherTest {
+
+ // data
+ public static final int BYTEBUFFER_SIZE = 1000;
+ public String[] cipherTests = null;
+ Properties props = null;
+ String cipherClass = null;
+ CipherTransformation[] transformations = null;
+
+ // cipher
+ static final byte[] KEY = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
+ static final byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+ Cipher enc, dec;
+
+ @Before
+ public void setup() {
+ init();
+ Utils.checkNotNull(cipherClass);
+ Utils.checkNotNull(transformations);
+ props = new Properties();
+ props.setProperty(ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_KEY,
+ cipherClass);
+ }
+
+ protected abstract void init() ;
+
+ @Test
+ public void cryptoTest() throws GeneralSecurityException, IOException {
+ for (CipherTransformation tran : transformations) {
+ /** uses the small data set in {@link TestData} */
+ cipherTests = TestData.getTestData(tran);
+ for (int i = 0; i != cipherTests.length; i += 5) {
+ byte[] key = DatatypeConverter.parseHexBinary(cipherTests[i + 1]);
+ byte[] iv = DatatypeConverter.parseHexBinary(cipherTests[i + 2]);
+
+ byte[] inputBytes = DatatypeConverter.parseHexBinary(cipherTests[i + 3]);
+ byte[] outputBytes = DatatypeConverter.parseHexBinary(cipherTests[i + 4]);
+
+ ByteBuffer inputBuffer = ByteBuffer.allocateDirect(inputBytes.length);
+ ByteBuffer outputBuffer = ByteBuffer.allocateDirect(outputBytes.length);
+ inputBuffer.put(inputBytes);
+ inputBuffer.flip();
+ outputBuffer.put(outputBytes);
+ outputBuffer.flip();
+
+ byteBufferTest(tran,key, iv, inputBuffer, outputBuffer);
+ byteArrayTest(tran, key, iv, inputBytes, outputBytes);
+ }
+
+ /** uses randomly generated big data set */
+ byteArrayTest(tran, KEY, IV);
+ }
+ }
+
+ private void byteBufferTest(CipherTransformation transformation, byte[] key,
+ byte[] iv,
+ ByteBuffer input, ByteBuffer output) throws
+ GeneralSecurityException, IOException {
+ ByteBuffer decResult = ByteBuffer.allocateDirect(BYTEBUFFER_SIZE);
+ ByteBuffer encResult = ByteBuffer.allocateDirect(BYTEBUFFER_SIZE);
+ Cipher enc, dec;
+
+ enc = getCipher(transformation);
+ dec = getCipher(transformation);
+
+ try {
+ enc.init(Cipher.ENCRYPT_MODE, key, iv);
+ } catch (Exception e) {
+ Assert.fail("AES failed initialisation - " + e.toString());
+ }
+
+ try {
+ dec.init(Cipher.DECRYPT_MODE, key, iv);
+ } catch (Exception e) {
+ Assert.fail("AES failed initialisation - " + e.toString());
+ }
+
+ //
+ // encryption pass
+ //
+ enc.doFinal(input, encResult);
+ input.flip();
+ encResult.flip();
+ if (!output.equals(encResult)) {
+ byte[] b = new byte[output.remaining()];
+ output.get(b);
+ byte[] c = new byte[encResult.remaining()];
+ encResult.get(c);
+ Assert.fail("AES failed encryption - expected " + new String(
+ DatatypeConverter
+ .printHexBinary(b)) + " got " + new String(
+ DatatypeConverter.printHexBinary(c)));
+ }
+
+ //
+ // decryption pass
+ //
+ dec.doFinal(encResult, decResult);
+ decResult.flip();
+
+ if (!input.equals(decResult)) {
+ byte[] inArray = new byte[input.remaining()];
+ byte[] decResultArray = new byte[decResult.remaining()];
+ input.get(inArray);
+ decResult.get(decResultArray);
+ Assert.fail();
+ }
+ }
+
+ /** test byte array whose data is planned in {@link TestData} */
+ private void byteArrayTest(CipherTransformation transformation, byte[] key,
+ byte[] iv, byte[] input, byte[] output) throws GeneralSecurityException {
+ resetCipher(transformation, key, iv);
+ int blockSize = transformation.getAlgorithmBlockSize();
+
+ byte[] temp = new byte[input.length + blockSize];
+ int n = enc.doFinal(input, 0, input.length, temp, 0);
+ byte[] cipherText = new byte[n];
+ System.arraycopy(temp, 0, cipherText, 0, n);
+ Assert.assertArrayEquals("byte array encryption error.", output, cipherText);
+
+ temp = new byte[cipherText.length + blockSize];
+ int m = dec.doFinal(cipherText, 0, cipherText.length, temp, 0);
+ byte[] plainText = new byte[m];
+ System.arraycopy(temp, 0, plainText, 0, m);
+ Assert.assertArrayEquals("byte array decryption error.", input, plainText);
+ }
+
+ /** test byte array whose data is randomly generated */
+ private void byteArrayTest(CipherTransformation transformation, byte[] key,
+ byte[] iv) throws GeneralSecurityException {
+ int blockSize = transformation.getAlgorithmBlockSize();
+
+ // AES_CBC_NOPADDING only accepts data whose size is the multiple of block size
+ int[] dataLenList = (transformation == CipherTransformation.AES_CBC_NOPADDING)
+ ? new int[] {10 * 1024} : new int[] {10 * 1024, 10 * 1024 - 3};
+ for (int dataLen : dataLenList) {
+ byte[] plainText = new byte[dataLen];
+ Random random = new SecureRandom();
+ random.nextBytes(plainText);
+ byte[] cipherText = new byte[dataLen + blockSize];
+
+ // check update method with inputs whose sizes are the multiple of block size or not
+ int[] bufferLenList = new int[] {2 * 1024 - 128, 2 * 1024 - 125};
+ for (int bufferLen : bufferLenList) {
+ resetCipher(transformation, key, iv);
+
+ int offset = 0;
+ // encrypt (update + doFinal) the data
+ int cipherPos = 0;
+ for (int i = 0; i < dataLen / bufferLen; i ++) {
+ cipherPos += enc.update(plainText, offset, bufferLen, cipherText, cipherPos);
+ offset += bufferLen;
+ }
+ cipherPos += enc.doFinal(plainText, offset, dataLen % bufferLen, cipherText, cipherPos);
+
+ offset = 0;
+ // decrypt (update + doFinal) the data
+ byte[] realPlainText = new byte[cipherPos + blockSize];
+ int plainPos = 0;
+ for (int i = 0; i < cipherPos / bufferLen; i ++) {
+ plainPos += dec.update(cipherText, offset, bufferLen, realPlainText, plainPos);
+ offset += bufferLen;
+ }
+ plainPos += dec.doFinal(cipherText, offset, cipherPos % bufferLen, realPlainText, plainPos);
+
+ // verify
+ Assert.assertEquals("random byte array length changes after transformation",
+ dataLen, plainPos);
+
+ byte[] shrinkPlainText = new byte[plainPos];
+ System.arraycopy(realPlainText, 0, shrinkPlainText, 0, plainPos);
+ Assert.assertArrayEquals("random byte array contents changes after transformation",
+ plainText, shrinkPlainText);
+ }
+ }
+ }
+
+ private void resetCipher(CipherTransformation transformation, byte[] key, byte[] iv) {
+ enc = getCipher(transformation);
+ dec = getCipher(transformation);
+
+ try {
+ enc.init(Cipher.ENCRYPT_MODE, key, iv);
+ } catch (Exception e) {
+ Assert.fail("AES failed initialisation - " + e.toString());
+ }
+
+ try {
+ dec.init(Cipher.DECRYPT_MODE, key, iv);
+ } catch (Exception e) {
+ Assert.fail("AES failed initialisation - " + e.toString());
+ }
+ }
+
+ private Cipher getCipher(CipherTransformation transformation) {
+ try {
+ return (Cipher) ReflectionUtils
+ .newInstance(ReflectionUtils.getClassByName(cipherClass), props,
+ transformation);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/cipher/JceCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/cipher/JceCipherTest.java b/src/test/java/org/apache/commons/crypto/cipher/JceCipherTest.java
new file mode 100644
index 0000000..c40aaa1
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/cipher/JceCipherTest.java
@@ -0,0 +1,32 @@
+/**
+ * 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;
+
+public class JceCipherTest extends AbstractCipherTest {
+
+ @Override
+ public void init() {
+ transformations = new CipherTransformation[]{
+ CipherTransformation.AES_CBC_NOPADDING,
+ CipherTransformation.AES_CBC_PKCS5PADDING,
+ CipherTransformation.AES_CTR_NOPADDING};
+ cipherClass = JceCipher.class.getName();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/cipher/OpensslCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/cipher/OpensslCipherTest.java b/src/test/java/org/apache/commons/crypto/cipher/OpensslCipherTest.java
new file mode 100644
index 0000000..c1ef849
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/cipher/OpensslCipherTest.java
@@ -0,0 +1,165 @@
+/**
+ * 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;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class OpensslCipherTest extends AbstractCipherTest {
+
+ @Override
+ public void init() {
+ transformations = new CipherTransformation[]{
+ CipherTransformation.AES_CBC_NOPADDING,
+ CipherTransformation.AES_CBC_PKCS5PADDING,
+ CipherTransformation.AES_CTR_NOPADDING};
+ cipherClass = OpensslCipher.class.getName();
+ }
+
+ @Test(expected = NoSuchAlgorithmException.class, timeout=120000)
+ public void testInvalidAlgorithm() throws Exception {
+ Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
+
+ try {
+ Openssl cipher = Openssl.getInstance("AES2/CTR/NoPadding");
+ Assert.fail("Should specify correct algorithm.");
+ } catch (NoSuchAlgorithmException e) {
+ Assert.assertTrue(e.getMessage().contains("Doesn't support algorithm: AES2 and mode: CTR"));
+ throw e;
+ }
+ }
+
+ @Test(expected = NoSuchPaddingException.class, timeout=120000)
+ public void testInvalidPadding() throws Exception {
+ Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
+
+ try {
+ Openssl cipher = Openssl.getInstance("AES/CTR/NoPadding2");
+ Assert.fail("Should specify correct padding.");
+ } catch (NoSuchPaddingException e) {
+ Assert.assertTrue(e.getMessage().contains("Doesn't support padding: NoPadding2"));
+ throw e;
+ }
+ }
+
+ @Test(expected = NoSuchAlgorithmException.class, timeout=120000)
+ public void testInvalidMode() throws Exception {
+ try {
+ Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
+ Openssl cipher = Openssl.getInstance("AES/CTR2/NoPadding");
+ Assert.fail("java.security.NoSuchAlgorithmException should be thrown.");
+ } catch (NoSuchAlgorithmException e) {
+ Assert.assertTrue(e.getMessage().contains("Doesn't support algorithm: AES and mode: CTR2"));
+ throw e;
+ }
+ }
+
+ @Test(timeout=120000)
+ public void testUpdateArguments() throws Exception {
+ Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
+ Openssl cipher = Openssl.getInstance(CipherTransformation.AES_CTR_NOPADDING.getName());
+ Assert.assertNotNull(cipher);
+
+ cipher.init(Openssl.ENCRYPT_MODE, KEY, IV);
+
+ // Require direct buffers
+ ByteBuffer input = ByteBuffer.allocate(1024);
+ ByteBuffer output = ByteBuffer.allocate(1024);
+
+ try {
+ cipher.update(input, output);
+ Assert.fail("Input and output buffer should be direct buffer.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue(e.getMessage().contains("Direct buffers are required"));
+ }
+
+ // Output buffer length should be sufficient to store output data
+ input = ByteBuffer.allocateDirect(1024);
+ output = ByteBuffer.allocateDirect(1000);
+ try {
+ cipher.update(input, output);
+ Assert.fail("Output buffer length should be sufficient " +
+ "to store output data");
+ } catch (ShortBufferException e) {
+ Assert.assertTrue(e.getMessage().contains("Output buffer is not sufficient"));
+ }
+ }
+
+ @Test(timeout=120000)
+ public void testDoFinalArguments() throws Exception {
+ Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
+ Openssl cipher = Openssl.getInstance(CipherTransformation.AES_CTR_NOPADDING.getName());
+ Assert.assertNotNull(cipher);
+
+ cipher.init(Openssl.ENCRYPT_MODE, KEY, IV);
+
+ // Require direct buffer
+ ByteBuffer output = ByteBuffer.allocate(1024);
+
+ try {
+ cipher.doFinal(output);
+ Assert.fail("Output buffer should be direct buffer.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue(e.getMessage().contains("Direct buffer is required"));
+ }
+ }
+
+ @Test(expected = InvalidKeyException.class, timeout=120000)
+ public void testInvalidKey() throws Exception {
+ Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
+ Openssl cipher = Openssl.getInstance(CipherTransformation.AES_CTR_NOPADDING.getName());
+ Assert.assertNotNull(cipher);
+
+ final byte[] invalidKey = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11};
+ try {
+ cipher.init(Openssl.ENCRYPT_MODE, invalidKey, IV);
+ Assert.fail("java.security.InvalidKeyException should be thrown.");
+ } catch (Exception e) {
+ Assert.assertTrue(e.getMessage().contains("Invalid key length."));
+ throw e;
+ }
+ }
+
+ @Test(expected = InvalidAlgorithmParameterException.class, timeout=120000)
+ public void testInvalidIV() throws Exception {
+ Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
+ Openssl cipher = Openssl.getInstance(CipherTransformation.AES_CTR_NOPADDING.getName());
+ Assert.assertNotNull(cipher);
+
+ final byte[] invalidIV = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11};
+ try {
+ cipher.init(Openssl.ENCRYPT_MODE, KEY, invalidIV);
+ Assert.fail("java.security.InvalidAlgorithmParameterException should be thrown.");
+ } catch (Exception e) {
+ Assert.assertTrue(e.getMessage().contains("Wrong IV length."));
+ throw e;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/cipher/TestData.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/cipher/TestData.java b/src/test/java/org/apache/commons/crypto/cipher/TestData.java
new file mode 100644
index 0000000..2f8da8f
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/cipher/TestData.java
@@ -0,0 +1,160 @@
+/**
+ * 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.util.HashMap;
+import java.util.Map;
+
+public class TestData {
+
+ private static String[] CBCNoPaddingTests = {
+ /*
+ * key_len,key,iv,plainText,cipherText
+ */
+ "128",
+ "2b7e151628aed2a6abf7158809cf4f3c",
+ "000102030405060708090a0b0c0d0e0f",
+ "6bc1bee22e409f96e93d7e117393172a",
+ "7649abac8119b246cee98e9b12e9197d",
+
+ "128",
+ "2b7e151628aed2a6abf7158809cf4f3c",
+ "7649ABAC8119B246CEE98E9B12E9197D",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "5086cb9b507219ee95db113a917678b2",
+
+ "192",
+ "603deb1015ca71be2b73aef0857d77811f352c073b6108d7",
+ "9CFC4E967EDB808D679F777BC6702C7D",
+ "30c81c46a35ce411e5fbc1191a0a52ef",
+ "78C57E3F543A18F472756DAC2F018523",
+
+ "192",
+ "603deb1015ca71be2b73aef0857d77811f352c073b6108d7",
+ "39F23369A9D9BACFA530E26304231461",
+ "f69f2445df4f9b17ad2b417be66c3710",
+ "79ECA9610F0B9AAFB8C7C2D655047A41",
+
+ "256",
+ "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
+ "000102030405060708090a0b0c0d0e0f",
+ "6bc1bee22e409f96e93d7e117393172a",
+ "f58c4c04d6e5f1ba779eabfb5f7bfbd6",
+
+ "256",
+ "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
+ "F58C4C04D6E5F1BA779EABFB5F7BFBD6",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "9cfc4e967edb808d679f777bc6702c7d"
+ };
+
+ private static String[] CBCPKCS5PaddingTests = {
+ /*
+ * key_len,key,iv,plainText,cipherText
+ */
+ //Test#0 for input of 6 bytes
+ "128",
+ "ac5800ac3cb59c7c14f36019e43b44fe",
+ "f013ce1ec901b5b60a85a986b3b72eba",
+ "f6cee5ff28fd",
+ "e8a846fd9718507371604504d4ca1ac7",
+
+ //Test#0 for input of 15 bytes
+ "128",
+ "0784fa652e733cb699f250b0df2c4b41",
+ "106519760fb3ef97e1ccea073b27122d",
+ "6842455a2992c2e5193056a5524075",
+ "56a8e0c3ee3315f913693c0ca781e917",
+
+ //Test#0 for input of 16 bytes
+ "128",
+ "04952c3fcf497a4d449c41e8730c5d9a",
+ "53549bf7d5553b727458c1abaf0ba167",
+ "c9a44f6f75e98ddbca7332167f5c45e3",
+ "7fa290322ca7a1a04b61a1147ff20fe66fde58510a1d0289d11c0ddf6f4decfd",
+
+ //Test#0 for input of 32 bytes
+ "128",
+ "2ae7081caebe54909820620a44a60a0f",
+ "fc5e783fbe7be12f58b1f025d82ada50",
+ "1ba93ee6f83752df47909585b3f28e56693f89e169d3093eee85175ea3a46cd3",
+ "7944957a99e473e2c07eb496a83ec4e55db2fb44ebdd42bb611e0def29b23a73ac37eb0f4f5d86f090f3ddce3980425a",
+
+ //Test#0 for input of 33 bytes
+ "128",
+ "898be9cc5004ed0fa6e117c9a3099d31",
+ "9dea7621945988f96491083849b068df",
+ "0397f4f6820b1f9386f14403be5ac16e50213bd473b4874b9bcbf5f318ee686b1d",
+ "e232cd6ef50047801ee681ec30f61d53cfd6b0bca02fd03c1b234baa10ea82ac9dab8b960926433a19ce6dea08677e34"};
+
+ private static String[] cipherCTRTests = {
+ /*
+ * key_len,key,iv,plainText,cipherText
+ */
+ "128",
+ "2b7e151628aed2a6abf7158809cf4f3c",
+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+ "6bc1bee22e409f96e93d7e117393172a",
+ "874d6191b620e3261bef6864990db6ce",
+
+ "128",
+ "2b7e151628aed2a6abf7158809cf4f3c",
+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "9806f66b7970fdff8617187bb9fffdff",
+
+ //Test for input of 15 bytes
+ "128",
+ "2b7e151628aed2a6abf7158809cf4f3c",
+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ "30c81c46a35ce411e5fbc1191a0a52",
+ "5ae4df3edbd5d35e5b4f09020db03e",
+
+ "256",
+ "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+ "6bc1bee22e409f96e93d7e117393172a",
+ "601ec313775789a5b7a7f504bbf3d228",
+
+ "256",
+ "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "f443e3ca4d62b59aca84e990cacaf5c5",
+
+ //Test for input of 15 bytes
+ "256",
+ "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
+ "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ "30c81c46a35ce411e5fbc1191a0a52",
+ "2b0930daa23de94ce87017ba2d8498" };
+
+ private static Map<CipherTransformation, String[]> testData =
+ new HashMap<CipherTransformation, String[]>();
+
+ static {
+ testData.put(CipherTransformation.AES_CBC_NOPADDING, CBCNoPaddingTests);
+ testData.put(CipherTransformation.AES_CBC_PKCS5PADDING,
+ CBCPKCS5PaddingTests);
+ testData.put(CipherTransformation.AES_CTR_NOPADDING, cipherCTRTests);
+ }
+
+ public static String[] getTestData(CipherTransformation transformation) {
+ return testData.get(transformation);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java b/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java
new file mode 100644
index 0000000..6c6f692
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public abstract class AbstractRandomTest {
+
+ public abstract SecureRandom getSecureRandom() throws IOException;
+
+ @Test(timeout=120000)
+ public void testRandomBytes() throws Exception {
+ SecureRandom random = getSecureRandom();
+ // len = 16
+ checkRandomBytes(random, 16);
+ // len = 32
+ checkRandomBytes(random, 32);
+ // len = 128
+ checkRandomBytes(random, 128);
+ // len = 256
+ checkRandomBytes(random, 256);
+ random.close();
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ private void checkRandomBytes(SecureRandom random, int len) {
+ byte[] bytes = new byte[len];
+ byte[] bytes1 = new byte[len];
+ random.nextBytes(bytes);
+ random.nextBytes(bytes1);
+
+ while (Arrays.equals(bytes, bytes1)) {
+ random.nextBytes(bytes1);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/random/TestJavaSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/random/TestJavaSecureRandom.java b/src/test/java/org/apache/commons/crypto/random/TestJavaSecureRandom.java
new file mode 100644
index 0000000..a85b7f7
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/random/TestJavaSecureRandom.java
@@ -0,0 +1,40 @@
+/**
+ * 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;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.commons.crypto.conf.ConfigurationKeys;
+import static junit.framework.Assert.fail;
+
+public class TestJavaSecureRandom extends AbstractRandomTest {
+
+ @Override
+ public SecureRandom getSecureRandom() throws IOException {
+ Properties props = new Properties();
+ props.setProperty(ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY,
+ JavaSecureRandom.class.getName());
+ SecureRandom random = SecureRandomFactory.getSecureRandom(props);
+ if ( !(random instanceof JavaSecureRandom)) {
+ fail("The SecureRandom should be: " + JavaSecureRandom.class.getName());
+ }
+ return random;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/random/TestOpensslSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/random/TestOpensslSecureRandom.java b/src/test/java/org/apache/commons/crypto/random/TestOpensslSecureRandom.java
new file mode 100644
index 0000000..514d547
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/random/TestOpensslSecureRandom.java
@@ -0,0 +1,40 @@
+/**
+ * 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;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.commons.crypto.conf.ConfigurationKeys;
+import static junit.framework.Assert.fail;
+
+public class TestOpensslSecureRandom extends AbstractRandomTest {
+
+ @Override
+ public SecureRandom getSecureRandom() throws IOException {
+ Properties props = new Properties();
+ props.setProperty(ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY,
+ OpensslSecureRandom.class.getName());
+ SecureRandom random = SecureRandomFactory.getSecureRandom(props);
+ if ( !(random instanceof OpensslSecureRandom)) {
+ fail("The SecureRandom should be: " + OpensslSecureRandom.class.getName());
+ }
+ return random;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/random/TestOsSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/random/TestOsSecureRandom.java b/src/test/java/org/apache/commons/crypto/random/TestOsSecureRandom.java
new file mode 100644
index 0000000..138f766
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/random/TestOsSecureRandom.java
@@ -0,0 +1,29 @@
+/**
+ * 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;
+
+import java.io.IOException;
+import java.util.Properties;
+
+public class TestOsSecureRandom extends AbstractRandomTest{
+
+ @Override
+ public SecureRandom getSecureRandom() throws IOException {
+ return new OsSecureRandom(new Properties());
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/stream/AbstractCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/stream/AbstractCryptoStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/AbstractCryptoStreamTest.java
new file mode 100644
index 0000000..fe73f00
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/stream/AbstractCryptoStreamTest.java
@@ -0,0 +1,456 @@
+/**
+ * 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.stream;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.security.SecureRandom;
+import java.util.Properties;
+import java.util.Random;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+import org.apache.commons.crypto.cipher.JceCipher;
+import org.apache.commons.crypto.cipher.Openssl;
+import org.apache.commons.crypto.cipher.OpensslCipher;
+import org.apache.commons.crypto.utils.ReflectionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public abstract class AbstractCryptoStreamTest {
+ private static final Log LOG= LogFactory.getLog(AbstractCryptoStreamTest.class);
+
+ private final int dataLen = 20000;
+ private byte[] data = new byte[dataLen];
+ private byte[] encData;
+ private Properties props = new Properties();
+ protected byte[] key = new byte[16];
+ private byte[] iv = new byte[16];
+ private int count = 10000;
+ protected static int defaultBufferSize = 8192;
+ protected static int smallBufferSize = 1024;
+
+ private final String jceCipherClass = JceCipher.class.getName();
+ private final String opensslCipherClass = OpensslCipher.class.getName();
+ protected CipherTransformation transformation;
+
+ public abstract void setUp() throws IOException;
+
+ @Before
+ public void before() throws IOException {
+ Random random = new SecureRandom();
+ random.nextBytes(data);
+ random.nextBytes(key);
+ random.nextBytes(iv);
+ setUp();
+ prepareData();
+ }
+
+ /** Test skip. */
+ @Test(timeout=120000)
+ public void testSkip() throws Exception {
+ doSkipTest(jceCipherClass, false);
+ doSkipTest(opensslCipherClass, false);
+
+ doSkipTest(jceCipherClass, true);
+ doSkipTest(opensslCipherClass, true);
+ }
+
+ /** Test byte buffer read with different buffer size. */
+ @Test(timeout=120000)
+ public void testByteBufferRead() throws Exception {
+ doByteBufferRead(jceCipherClass, false);
+ doByteBufferRead(opensslCipherClass, false);
+
+ doByteBufferRead(jceCipherClass, true);
+ doByteBufferRead(opensslCipherClass, true);
+ }
+
+ /** Test byte buffer write. */
+ @Test(timeout=120000)
+ public void testByteBufferWrite() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ doByteBufferWrite(jceCipherClass, baos, false);
+ doByteBufferWrite(opensslCipherClass, baos, false);
+
+ doByteBufferWrite(jceCipherClass, baos, true);
+ doByteBufferWrite(opensslCipherClass, baos, true);
+ }
+
+ private void doSkipTest(String cipherClass, boolean withChannel) throws IOException {
+ InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), defaultBufferSize, iv, withChannel);
+ byte[] result = new byte[dataLen];
+ int n1 = readAll(in, result, 0, dataLen / 3);
+
+ long skipped = in.skip(dataLen / 3);
+ int n2 = readAll(in, result, 0, dataLen);
+
+ Assert.assertEquals(dataLen, n1 + skipped + n2);
+ byte[] readData = new byte[n2];
+ System.arraycopy(result, 0, readData, 0, n2);
+ byte[] expectedData = new byte[n2];
+ System.arraycopy(data, dataLen - n2, expectedData, 0, n2);
+ Assert.assertArrayEquals(readData, expectedData);
+
+ try {
+ skipped = in.skip(-3);
+ Assert.fail("Skip Negative length should fail.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue(e.getMessage().contains("Negative skip length"));
+ }
+
+ // Skip after EOF
+ skipped = in.skip(3);
+ Assert.assertEquals(skipped, 0);
+
+ in.close();
+ }
+
+ private void doByteBufferRead(String cipherClass, boolean withChannel) throws Exception {
+ // Default buffer size, initial buffer position is 0
+ InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), defaultBufferSize, iv, withChannel);
+ ByteBuffer buf = ByteBuffer.allocate(dataLen + 100);
+ byteBufferReadCheck(in, buf, 0);
+ in.close();
+
+ // Default buffer size, initial buffer position is not 0
+ in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), defaultBufferSize, iv, withChannel);
+ buf.clear();
+ byteBufferReadCheck(in, buf, 11);
+ in.close();
+
+ // Small buffer size, initial buffer position is 0
+ in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), smallBufferSize, iv, withChannel);
+ buf.clear();
+ byteBufferReadCheck(in, buf, 0);
+ in.close();
+
+ // Small buffer size, initial buffer position is not 0
+ in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), smallBufferSize, iv, withChannel);
+ buf.clear();
+ byteBufferReadCheck(in, buf, 11);
+ in.close();
+
+ // Direct buffer, default buffer size, initial buffer position is 0
+ in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), defaultBufferSize, iv, withChannel);
+ buf = ByteBuffer.allocateDirect(dataLen + 100);
+ byteBufferReadCheck(in, buf, 0);
+ in.close();
+
+ // Direct buffer, default buffer size, initial buffer position is not 0
+ in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), defaultBufferSize, iv, withChannel);
+ buf.clear();
+ byteBufferReadCheck(in, buf, 11);
+ in.close();
+
+ // Direct buffer, small buffer size, initial buffer position is 0
+ in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), smallBufferSize, iv, withChannel);
+ buf.clear();
+ byteBufferReadCheck(in, buf, 0);
+ in.close();
+
+ // Direct buffer, small buffer size, initial buffer position is not 0
+ in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), smallBufferSize, iv, withChannel);
+ buf.clear();
+ byteBufferReadCheck(in, buf, 11);
+ in.close();
+ }
+
+ private void doByteBufferWrite(String cipherClass, ByteArrayOutputStream baos,
+ boolean withChannel)
+ throws Exception {
+ baos.reset();
+ CryptoOutputStream out =
+ getCryptoOutputStream(baos, getCipher(cipherClass), defaultBufferSize,
+ iv, withChannel);
+ ByteBuffer buf = ByteBuffer.allocateDirect(dataLen / 2);
+ buf.put(data, 0, dataLen / 2);
+ buf.flip();
+ int n1 = out.write(buf);
+
+ buf.clear();
+ buf.put(data, n1, dataLen / 3);
+ buf.flip();
+ int n2 = out.write(buf);
+
+ buf.clear();
+ buf.put(data, n1 + n2, dataLen - n1 - n2);
+ buf.flip();
+ int n3 = out.write(buf);
+
+ Assert.assertEquals(dataLen, n1 + n2 + n3);
+
+ out.flush();
+
+ InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData),
+ getCipher(cipherClass), defaultBufferSize, iv, withChannel);
+ buf = ByteBuffer.allocate(dataLen + 100);
+ byteBufferReadCheck(in, buf, 0);
+ in.close();
+ }
+
+ private void byteBufferReadCheck(InputStream in, ByteBuffer buf,
+ int bufPos) throws Exception {
+ buf.position(bufPos);
+ int n = ((ReadableByteChannel) in).read(buf);
+ Assert.assertEquals(bufPos + n, buf.position());
+ byte[] readData = new byte[n];
+ buf.rewind();
+ buf.position(bufPos);
+ buf.get(readData);
+ byte[] expectedData = new byte[n];
+ System.arraycopy(data, 0, expectedData, 0, n);
+ Assert.assertArrayEquals(readData, expectedData);
+ }
+
+ private void prepareData() throws IOException {
+ Cipher cipher = null;
+ try {
+ cipher = (Cipher)ReflectionUtils.newInstance(
+ ReflectionUtils.getClassByName(jceCipherClass), props, transformation);
+ } catch (ClassNotFoundException cnfe) {
+ throw new IOException("Illegal crypto cipher!");
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStream out = new CryptoOutputStream(baos, cipher, defaultBufferSize, key, iv);
+ out.write(data);
+ out.flush();
+ out.close();
+ encData = baos.toByteArray();
+ }
+
+ protected CryptoInputStream getCryptoInputStream(ByteArrayInputStream bais,
+ Cipher cipher,
+ int bufferSize, byte[] iv,
+ boolean withChannel) throws
+ IOException {
+ if (withChannel) {
+ return new CryptoInputStream(Channels.newChannel(bais), cipher,
+ bufferSize, key, iv);
+ } else {
+ return new CryptoInputStream(bais, cipher, bufferSize, key, iv);
+ }
+ }
+
+ protected CryptoOutputStream getCryptoOutputStream(ByteArrayOutputStream baos,
+ Cipher cipher,
+ int bufferSize, byte[] iv,
+ boolean withChannel) throws
+ IOException {
+ if (withChannel) {
+ return new CryptoOutputStream(Channels.newChannel(baos), cipher,
+ bufferSize, key, iv);
+ } else {
+ return new CryptoOutputStream(baos, cipher, bufferSize, key, iv);
+ }
+ }
+
+ private int readAll(InputStream in, byte[] b, int offset, int len)
+ throws IOException {
+ int n = 0;
+ int total = 0;
+ while (n != -1) {
+ total += n;
+ if (total >= len) {
+ break;
+ }
+ n = in.read(b, offset + total, len - total);
+ }
+
+ return total;
+ }
+
+ protected Cipher getCipher(String cipherClass) throws IOException {
+ try {
+ return (Cipher)ReflectionUtils.newInstance(
+ ReflectionUtils.getClassByName(cipherClass), props, transformation);
+ } catch (ClassNotFoundException cnfe) {
+ throw new IOException("Illegal crypto cipher!");
+ }
+ }
+
+ @Test
+ public void testReadWrite() throws Exception {
+ Assert.assertEquals(null, Openssl.getLoadingFailureReason());
+ doReadWriteTest(0, jceCipherClass, jceCipherClass, iv);
+ doReadWriteTest(0, opensslCipherClass, opensslCipherClass, iv);
+ doReadWriteTest(count, jceCipherClass, jceCipherClass, iv);
+ doReadWriteTest(count, opensslCipherClass, opensslCipherClass, iv);
+ doReadWriteTest(count, jceCipherClass, opensslCipherClass, iv);
+ doReadWriteTest(count, opensslCipherClass, jceCipherClass, iv);
+ // Overflow test, IV: xx xx xx xx xx xx xx xx ff ff ff ff ff ff ff ff
+ for(int i = 0; i < 8; i++) {
+ iv[8 + i] = (byte) 0xff;
+ }
+ doReadWriteTest(count, jceCipherClass, jceCipherClass, iv);
+ doReadWriteTest(count, opensslCipherClass, opensslCipherClass, iv);
+ doReadWriteTest(count, jceCipherClass, opensslCipherClass, iv);
+ doReadWriteTest(count, opensslCipherClass, jceCipherClass, iv);
+ }
+
+ private void doReadWriteTest(int count, String encCipherClass,
+ String decCipherClass, byte[] iv) throws IOException {
+ doReadWriteTestForInputStream(count, encCipherClass, decCipherClass, iv);
+ doReadWriteTestForReadableByteChannel(count, encCipherClass, decCipherClass,
+ iv);
+ }
+
+ private void doReadWriteTestForInputStream(int count, String encCipherClass,
+ String decCipherClass, byte[] iv) throws IOException {
+ Cipher encCipher = getCipher(encCipherClass);
+ LOG.debug("Created a cipher object of type: " + encCipherClass);
+
+ // Generate data
+ SecureRandom random = new SecureRandom();
+ byte[] originalData = new byte[count];
+ byte[] decryptedData = new byte[count];
+ random.nextBytes(originalData);
+ LOG.debug("Generated " + count + " records");
+
+ // Encrypt data
+ ByteArrayOutputStream encryptedData = new ByteArrayOutputStream();
+ CryptoOutputStream out =
+ getCryptoOutputStream(encryptedData, encCipher, defaultBufferSize, iv,
+ false);
+ out.write(originalData, 0, originalData.length);
+ out.flush();
+ out.close();
+ LOG.debug("Finished encrypting data");
+
+ Cipher decCipher = getCipher(decCipherClass);
+ LOG.debug("Created a cipher object of type: " + decCipherClass);
+
+ // Decrypt data
+ CryptoInputStream in = getCryptoInputStream(
+ new ByteArrayInputStream(encryptedData.toByteArray()), decCipher,
+ defaultBufferSize, iv, false);
+
+ // Check
+ int remainingToRead = count;
+ int offset = 0;
+ while (remainingToRead > 0) {
+ int n = in.read(decryptedData, offset, decryptedData.length - offset);
+ if (n >=0) {
+ remainingToRead -= n;
+ offset += n;
+ }
+ }
+
+ Assert.assertArrayEquals("originalData and decryptedData not equal",
+ originalData, decryptedData);
+
+ // Decrypt data byte-at-a-time
+ in = getCryptoInputStream(
+ new ByteArrayInputStream(encryptedData.toByteArray()), decCipher,
+ defaultBufferSize, iv, false);
+
+ // Check
+ DataInputStream originalIn = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(originalData)));
+ int expected;
+ do {
+ expected = originalIn.read();
+ Assert.assertEquals("Decrypted stream read by byte does not match",
+ expected, in.read());
+ } while (expected != -1);
+
+ LOG.debug("SUCCESS! Completed checking " + count + " records");
+ }
+
+ private void doReadWriteTestForReadableByteChannel(int count,
+ String encCipherClass,
+ String decCipherClass,
+ byte[] iv) throws IOException {
+ Cipher encCipher = getCipher(encCipherClass);
+ LOG.debug("Created a cipher object of type: " + encCipherClass);
+
+ // Generate data
+ SecureRandom random = new SecureRandom();
+ byte[] originalData = new byte[count];
+ byte[] decryptedData = new byte[count];
+ random.nextBytes(originalData);
+ LOG.debug("Generated " + count + " records");
+
+ // Encrypt data
+ ByteArrayOutputStream encryptedData = new ByteArrayOutputStream();
+ CryptoOutputStream out =
+ getCryptoOutputStream(encryptedData, encCipher, defaultBufferSize, iv,
+ true);
+ out.write(originalData, 0, originalData.length);
+ out.flush();
+ out.close();
+ LOG.debug("Finished encrypting data");
+
+ Cipher decCipher = getCipher(decCipherClass);
+ LOG.debug("Created a cipher object of type: " + decCipherClass);
+
+ // Decrypt data
+ CryptoInputStream in = getCryptoInputStream(
+ new ByteArrayInputStream(encryptedData.toByteArray()), decCipher,
+ defaultBufferSize, iv, true);
+
+ // Check
+ int remainingToRead = count;
+ int offset = 0;
+ while (remainingToRead > 0) {
+ int n = in.read(decryptedData, offset, decryptedData.length - offset);
+ if (n >=0) {
+ remainingToRead -= n;
+ offset += n;
+ }
+ }
+
+ Assert.assertArrayEquals("originalData and decryptedData not equal",
+ originalData, decryptedData);
+
+ // Decrypt data byte-at-a-time
+ in = getCryptoInputStream(new ByteArrayInputStream(
+ encryptedData.toByteArray()),decCipher,defaultBufferSize,iv,true);
+
+ // Check
+ DataInputStream originalIn = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(originalData)));
+ int expected;
+ do {
+ expected = originalIn.read();
+ Assert.assertEquals("Decrypted stream read by byte does not match",
+ expected, in.read());
+ } while (expected != -1);
+
+ LOG.debug("SUCCESS! Completed checking " + count + " records");
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/stream/CBCNoPaddingCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/stream/CBCNoPaddingCryptoStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/CBCNoPaddingCryptoStreamTest.java
new file mode 100644
index 0000000..743a3ac
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/stream/CBCNoPaddingCryptoStreamTest.java
@@ -0,0 +1,31 @@
+/**
+ * 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.stream;
+
+import java.io.IOException;
+
+import org.apache.commons.crypto.cipher.CipherTransformation;
+
+public class CBCNoPaddingCryptoStreamTest extends AbstractCryptoStreamTest {
+
+ public void setUp() throws IOException {
+ transformation = CipherTransformation
+ .AES_CBC_NOPADDING;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/stream/CBCPKCS5PaddingCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/stream/CBCPKCS5PaddingCryptoStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/CBCPKCS5PaddingCryptoStreamTest.java
new file mode 100644
index 0000000..cb65dac
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/stream/CBCPKCS5PaddingCryptoStreamTest.java
@@ -0,0 +1,30 @@
+/**
+ * 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.stream;
+
+import java.io.IOException;
+
+import org.apache.commons.crypto.cipher.CipherTransformation;
+
+public class CBCPKCS5PaddingCryptoStreamTest extends AbstractCryptoStreamTest {
+
+ public void setUp() throws IOException {
+ transformation = CipherTransformation
+ .AES_CBC_PKCS5PADDING;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/stream/CTRCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/stream/CTRCryptoStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/CTRCryptoStreamTest.java
new file mode 100644
index 0000000..1a50382
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/stream/CTRCryptoStreamTest.java
@@ -0,0 +1,58 @@
+/**
+ * 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.stream;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.channels.Channels;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+
+public class CTRCryptoStreamTest extends AbstractCryptoStreamTest {
+
+ public void setUp() throws IOException {
+ transformation = CipherTransformation
+ .AES_CTR_NOPADDING;
+ }
+
+ @Override
+ protected CTRCryptoInputStream getCryptoInputStream
+ (ByteArrayInputStream bais, Cipher cipher, int
+ bufferSize,byte[] iv, boolean withChannel)
+ throws IOException {
+ if (withChannel) {
+ return new CTRCryptoInputStream(Channels.newChannel(bais), cipher,
+ bufferSize, key, iv);
+ } else {
+ return new CTRCryptoInputStream(bais, cipher, bufferSize, key, iv);
+ }
+ }
+
+ @Override
+ protected CTRCryptoOutputStream getCryptoOutputStream(ByteArrayOutputStream baos,Cipher cipher, int
+ bufferSize, byte[] iv, boolean withChannel)
+ throws IOException {
+ if (withChannel) {
+ return new CTRCryptoOutputStream(Channels.newChannel(baos), cipher, bufferSize, key, iv);
+ } else {
+ return new CTRCryptoOutputStream(baos, cipher, bufferSize, key, iv);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/stream/CTRNoPaddingCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/stream/CTRNoPaddingCryptoStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/CTRNoPaddingCryptoStreamTest.java
new file mode 100644
index 0000000..1bbf600
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/stream/CTRNoPaddingCryptoStreamTest.java
@@ -0,0 +1,31 @@
+/**
+ * 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.stream;
+
+import java.io.IOException;
+
+import org.apache.commons.crypto.cipher.CipherTransformation;
+
+public class CTRNoPaddingCryptoStreamTest extends AbstractCryptoStreamTest {
+
+ public void setUp() throws IOException {
+ transformation = CipherTransformation
+ .AES_CTR_NOPADDING;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/stream/PositionedCryptoInputStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/stream/PositionedCryptoInputStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/PositionedCryptoInputStreamTest.java
new file mode 100644
index 0000000..5907ba8
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/stream/PositionedCryptoInputStreamTest.java
@@ -0,0 +1,381 @@
+/**
+ * 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.stream;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+import org.apache.commons.crypto.cipher.JceCipher;
+import org.apache.commons.crypto.cipher.OpensslCipher;
+import org.apache.commons.crypto.stream.input.Input;
+import org.apache.commons.crypto.utils.ReflectionUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.Random;
+
+public class PositionedCryptoInputStreamTest {
+
+ private final int dataLen = 20000;
+ private byte[] testData = new byte[dataLen];
+ private byte[] encData;
+ private Properties props = new Properties();
+ private byte[] key = new byte[16];
+ private byte[] iv = new byte[16];
+ int bufferSize = 2048;
+ int bufferSizeLess = bufferSize - 1;
+ int bufferSizeMore = bufferSize + 1;
+ int length = 1024;
+ int lengthLess = length - 1;
+ int lengthMore = length + 1;
+
+ private final String jceCipherClass = JceCipher.class.getName();
+ private final String opensslCipherClass = OpensslCipher.class.getName();
+ private CipherTransformation transformation =
+ CipherTransformation.AES_CTR_NOPADDING;
+
+ @Before
+ public void before() throws IOException {
+ Random random = new SecureRandom();
+ random.nextBytes(testData);
+ random.nextBytes(key);
+ random.nextBytes(iv);
+ prepareData();
+ }
+
+ private void prepareData() throws IOException {
+ Cipher cipher = null;
+ try {
+ cipher = (Cipher)ReflectionUtils.newInstance(
+ ReflectionUtils.getClassByName(jceCipherClass),
+ props, transformation);
+ } catch (ClassNotFoundException cnfe) {
+ throw new IOException("Illegal crypto cipher!");
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ // encryption data
+ OutputStream out = new CryptoOutputStream(baos, cipher, bufferSize, key, iv);
+ out.write(testData);
+ out.flush();
+ out.close();
+ encData = baos.toByteArray();
+ }
+
+ public void setUp() throws IOException {}
+
+ private PositionedCryptoInputStream getCryptoInputStream(Cipher cipher,
+ int bufferSize) throws IOException {
+ return new PositionedCryptoInputStream(new PositionedInputForTest(
+ Arrays.copyOf(encData, encData.length)), cipher, bufferSize, key, iv, 0);
+ }
+
+ @Test
+ public void doTest() throws Exception {
+ testCipher(jceCipherClass);
+ testCipher(opensslCipherClass);
+ }
+
+ private void testCipher(String cipherClass) throws Exception {
+ doPositionedReadTests(cipherClass);
+ doReadFullyTests(cipherClass);
+ doSeekTests(cipherClass);
+ doMultipleReadTest(cipherClass);
+ }
+
+ // when there are multiple positioned read actions and one read action,
+ // they will not interfere each other.
+ private void doMultipleReadTest(String cipherClass) throws Exception {
+ PositionedCryptoInputStream in = getCryptoInputStream(
+ getCipher(cipherClass), bufferSize);
+ int position = 0;
+ while (in.available() > 0) {
+ ByteBuffer buf = ByteBuffer.allocate(length);
+ byte[] bytes1 = new byte[length];
+ byte[] bytes2 = new byte[lengthLess];
+ // do the read and position read
+ int pn1 = in.read(position, bytes1, 0, length);
+ int n = in.read(buf);
+ int pn2 = in.read(position, bytes2, 0, lengthLess);
+
+ // verify the result
+ if (pn1 > 0) {
+ compareByteArray(testData, position, bytes1, pn1);
+ }
+
+ if (pn2 > 0) {
+ compareByteArray(testData, position, bytes2, pn2);
+ }
+
+ if (n > 0) {
+ compareByteArray(testData, position, buf.array(), n);
+ position += n;
+ } else {
+ break;
+ }
+ }
+ in.close();
+ }
+
+ private void doPositionedReadTests(String cipherClass) throws Exception {
+ // test with different bufferSize when position = 0
+ testPositionedReadLoop(cipherClass, 0, length, bufferSize, dataLen);
+ testPositionedReadLoop(cipherClass, 0, length, bufferSizeLess, dataLen);
+ testPositionedReadLoop(cipherClass, 0, length, bufferSizeMore, dataLen);
+ // test with different position when bufferSize = 2048
+ testPositionedReadLoop(cipherClass, dataLen / 2, length, bufferSize, dataLen);
+ testPositionedReadLoop(cipherClass, dataLen / 2 - 1, length,
+ bufferSizeLess, dataLen);
+ testPositionedReadLoop(cipherClass, dataLen / 2 + 1, length,
+ bufferSizeMore, dataLen);
+ // position = -1 or position = max length, read nothing and return -1
+ testPositionedReadNone(cipherClass, -1, length, bufferSize);
+ testPositionedReadNone(cipherClass, dataLen, length, bufferSize);
+ }
+
+ private void doReadFullyTests(String cipherClass) throws Exception {
+ // test with different bufferSize when position = 0
+ testReadFullyLoop(cipherClass, 0, length, bufferSize, dataLen);
+ testReadFullyLoop(cipherClass, 0, length, bufferSizeLess, dataLen);
+ testReadFullyLoop(cipherClass, 0, length, bufferSizeMore, dataLen);
+ // test with different length when position = 0
+ testReadFullyLoop(cipherClass, 0, length, bufferSize, dataLen);
+ testReadFullyLoop(cipherClass, 0, lengthLess, bufferSize, dataLen);
+ testReadFullyLoop(cipherClass, 0, lengthMore, bufferSize, dataLen);
+ // test read fully failed
+ testReadFullyFailed(cipherClass, -1, length, bufferSize);
+ testReadFullyFailed(cipherClass, dataLen, length, bufferSize);
+ testReadFullyFailed(cipherClass, dataLen - length + 1, length, bufferSize);
+ }
+
+ private void doSeekTests(String cipherClass) throws Exception {
+ // test with different length when position = 0
+ testSeekLoop(cipherClass, 0, length, bufferSize);
+ testSeekLoop(cipherClass, 0, lengthLess, bufferSize);
+ testSeekLoop(cipherClass, 0, lengthMore, bufferSize);
+ // there should be none data read when position = dataLen
+ testSeekLoop(cipherClass, dataLen, length, bufferSize);
+ // test exception when position = -1
+ testSeekFailed(cipherClass, -1, bufferSize);
+ }
+
+ private void testSeekLoop(String cipherClass, int position, int length,
+ int bufferSize) throws Exception {
+ PositionedCryptoInputStream in = getCryptoInputStream(
+ getCipher(cipherClass), bufferSize);
+ while (in.available() > 0) {
+ in.seek(position);
+ ByteBuffer buf = ByteBuffer.allocate(length);
+ int n = in.read(buf);
+ if (n > 0) {
+ compareByteArray(testData, position, buf.array(), n);
+ position += n;
+ } else {
+ break;
+ }
+ }
+ in.close();
+ }
+
+ // test for the out of index position, eg, -1.
+ private void testSeekFailed(String cipherClass, int position,
+ int bufferSize) throws Exception {
+ PositionedCryptoInputStream in = getCryptoInputStream(
+ getCipher(cipherClass), bufferSize);
+ try {
+ in.seek(position);
+ Assert.fail("Excepted exception for cannot seek to negative offset.");
+ } catch (IllegalArgumentException iae) {
+ }
+ in.close();
+ }
+
+ private void testPositionedReadLoop(String cipherClass, int position,
+ int length, int bufferSize, int total) throws Exception {
+ PositionedCryptoInputStream in = getCryptoInputStream(
+ getCipher(cipherClass), bufferSize);
+ // do the position read until the end of data
+ while (position < total) {
+ byte[] bytes = new byte[length];
+ int n = in.read(position, bytes, 0, length);
+ if (n >= 0) {
+ compareByteArray(testData, position, bytes, n);
+ position += n;
+ } else {
+ break;
+ }
+ }
+ in.close();
+ }
+
+ // test for the out of index position, eg, -1.
+ private void testPositionedReadNone(String cipherClass, int position,
+ int length, int bufferSize) throws Exception {
+ PositionedCryptoInputStream in = getCryptoInputStream(
+ getCipher(cipherClass), bufferSize);
+ byte[] bytes = new byte[length];
+ int n = in.read(position, bytes, 0, length);
+ Assert.assertEquals(n, -1);
+ in.close();
+ }
+
+ private void testReadFullyLoop(String cipherClass,int position,
+ int length, int bufferSize, int total) throws Exception {
+ PositionedCryptoInputStream in = getCryptoInputStream(
+ getCipher(cipherClass), bufferSize);
+
+ // do the position read full until remain < length
+ while (position + length <= total) {
+ byte[] bytes = new byte[length];
+ in.readFully(position, bytes, 0, length);
+ compareByteArray(testData, position, bytes, length);
+ position += length;
+ }
+
+ in.close();
+ }
+
+ // test for the End of file reached before reading fully
+ private void testReadFullyFailed(String cipherClass, int position,
+ int length, int bufferSize) throws Exception {
+ PositionedCryptoInputStream in = getCryptoInputStream(
+ getCipher(cipherClass), bufferSize);
+ byte[] bytes = new byte[length];
+ try {
+ in.readFully(position, bytes, 0, length);
+ Assert.fail("Excepted EOFException.");
+ } catch (IOException ioe) {
+ // excepted exception
+ }
+ in.close();
+ }
+
+ // compare the data from pos with length and data2 from 0 with length
+ private void compareByteArray(byte[] data1, int pos, byte[] data2, int length) {
+ byte[] expectedData = new byte[length];
+ byte[] realData = new byte[length];
+ // get the expected data with the position and length
+ System.arraycopy(data1, pos, expectedData, 0, length);
+ // get the real data
+ System.arraycopy(data2, 0, realData, 0, length);
+ Assert.assertArrayEquals(expectedData, realData);
+ }
+
+ private Cipher getCipher(String cipherClass) throws IOException {
+ try {
+ return (Cipher)ReflectionUtils.newInstance(
+ ReflectionUtils.getClassByName(cipherClass), props, transformation);
+ } catch (ClassNotFoundException cnfe) {
+ throw new IOException("Illegal crypto cipher!");
+ }
+ }
+
+ class PositionedInputForTest implements Input {
+
+ byte[] data;
+ long pos;
+ long count;
+
+ public PositionedInputForTest(byte[] data) {
+ this.data = data;
+ this.pos = 0;
+ this.count = data.length;
+ }
+
+ @Override
+ public int read(ByteBuffer dst) throws IOException {
+ int remaining = (int)(count - pos);
+ if(remaining <= 0) {
+ return -1;
+ }
+
+ int length = Math.min(dst.remaining(), remaining);
+ dst.put(data, (int)pos, length);
+ pos += length;
+ return length;
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ if (n <= 0) {
+ return 0;
+ }
+
+ long remaining = count - pos;
+ if(remaining < n) {
+ n = remaining;
+ }
+ pos += n;
+
+ return n;
+ }
+
+ @Override
+ public int read(long position, byte[] buffer, int offset, int length)
+ throws IOException {
+ if (buffer == null) {
+ throw new NullPointerException();
+ } else if (offset < 0 || length < 0 || length > buffer.length - offset) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ if (position < 0 || position >= count) {
+ return -1;
+ }
+
+ long avail = count - position;
+ if (length > avail) {
+ length = (int)avail;
+ }
+ if (length <= 0) {
+ return 0;
+ }
+ System.arraycopy(data, (int)position, buffer, offset, length);
+ return length;
+ }
+
+ @Override
+ public void seek(long position) throws IOException {
+ if (pos < 0) {
+ throw new IOException("Negative seek offset");
+ } else if (position >= 0 && position < count) {
+ pos = position;
+ } else {
+ // to the end of file
+ pos = count;
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public int available() throws IOException {
+ return (int)(count - pos);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/org/apache/commons/crypto/utils/UtilsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/utils/UtilsTest.java b/src/test/java/org/apache/commons/crypto/utils/UtilsTest.java
new file mode 100644
index 0000000..a0475be
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/utils/UtilsTest.java
@@ -0,0 +1,40 @@
+/**
+ * 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.utils;
+
+import junit.framework.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class UtilsTest {
+ @Test
+ public void testSplitOmitEmptyLine() {
+ List<String> clazzNames = Utils.splitClassNames("", ",");
+ Assert.assertEquals(Collections.<String>emptyList(), clazzNames);
+
+ clazzNames = Utils.splitClassNames("a,b", ",");
+ Assert.assertEquals(Arrays.asList("a", "b"), clazzNames);
+ clazzNames = Utils.splitClassNames("a,b,", ",");
+ Assert.assertEquals(Arrays.asList("a", "b"), clazzNames);
+ clazzNames = Utils.splitClassNames("a, b,", ",");
+ Assert.assertEquals(Arrays.asList("a", "b"), clazzNames);
+ }
+}
[5/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
Posted by xu...@apache.org.
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/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..57a8cc7
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java
@@ -0,0 +1,116 @@
+/**
+ * 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(genereted by javah).
+ */
+public class 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.
+ *
+ * @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/4920d272/src/main/java/org/apache/commons/crypto/cipher/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/package-info.java b/src/main/java/org/apache/commons/crypto/cipher/package-info.java
new file mode 100644
index 0000000..c650b57
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/package-info.java
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+/**
+ * Cipher classes
+ */
+package org.apache.commons.crypto.cipher;
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/conf/ConfigurationKeys.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/conf/ConfigurationKeys.java b/src/main/java/org/apache/commons/crypto/conf/ConfigurationKeys.java
new file mode 100644
index 0000000..d9c193f
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/conf/ConfigurationKeys.java
@@ -0,0 +1,139 @@
+/**
+ * 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.conf;
+
+import org.apache.commons.crypto.cipher.JceCipher;
+
+/**
+ * The ConfigurationKeys contains Configuration keys and default values.
+ */
+public class ConfigurationKeys {
+
+ /**
+ * The prefix named with project name.
+ */
+ public static final String CHIMERA_PREFIX = "chimera.";
+
+ /**
+ * The filename of configuration file.
+ */
+ public static final String CHIMERA_SYSTEM_PROPERTIES_FILE =
+ CHIMERA_PREFIX + "properties";
+
+ /**
+ * The prefix of crypto configuration.
+ */
+ public static final String CONF_PREFIX =
+ CHIMERA_PREFIX + "crypto.";
+
+ /**
+ * The configuration key of implementation class for crypto cipher.
+ * The values of CHIMERA_CRYPTO_CIPHER_CLASSES_KEY can be
+ * "org.apache.commons.crypto.cipher.JceCipher" and "org.apache.commons.crypto.cipher.OpensslCipher".
+ * And it takes a common separated list.
+ * The "org.apache.commons.crypto.cipher.JceCipher" use jce provider to
+ * implement {@link org.apache.commons.crypto.cipher.Cipher} and
+ * the "org.apache.commons.crypto.cipher.OpensslCipher" use jni into openssl to implement.
+ * Note that for each value,the first value which can be created without exception
+ * will be used (priority by order).
+ */
+ public static final String CHIMERA_CRYPTO_CIPHER_CLASSES_KEY =
+ CONF_PREFIX + "cipher.classes";
+
+ /**
+ * The default value for crypto cipher.
+ */
+ public static final String CHIMERA_CRYPTO_CIPHER_CLASSES_DEFAULT =
+ JceCipher.class.getName();
+
+ /**
+ * The configuration key of the provider class for JCE cipher.
+ */
+ public static final String CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY =
+ CONF_PREFIX + "cipher.jce.provider";
+
+ // security random related configuration keys
+ /**
+ * The configuration key of the file path for secure random device.
+ */
+ public static final String CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY =
+ CONF_PREFIX + "secure.random.device.file.path";
+
+ /**
+ * The default value of the file path for secure random device.
+ */
+ public static final String CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT =
+ "/dev/urandom";
+
+ /**
+ * The configuration key of the algorithm of secure random.
+ */
+ public static final String CHIMERA_CRYPTO_SECURE_RANDOM_JAVA_ALGORITHM_KEY =
+ CONF_PREFIX + "secure.random.java.algorithm";
+
+ /**
+ * The default value of the algorithm of secure random.
+ */
+ public static final String
+ CHIMERA_CRYPTO_SECURE_RANDOM_JAVA_ALGORITHM_DEFAULT = "SHA1PRNG";
+
+ /**
+ * The configuration key of the implementation class for secure random.
+ * The values of CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY can be
+ * "org.apache.commons.crypto.random.JavaSecureRandom" and "org.apache.commons.crypto.random.OpensslSecureRandom".
+ * And it takes a common separated list.
+ * The "org.apache.commons.crypto.random.JavaSecureRandom" use java to
+ * implement {@link org.apache.commons.crypto.random.SecureRandom} and
+ * the "org.apache.commons.crypto.random.OpensslSecureRandom" use jni into openssl to implement.
+ * Note that for each value,the first value which can be created without exception
+ * will be used (priority by order).
+ */
+ public static final String CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY =
+ CONF_PREFIX + "secure.random.classes";
+
+ /**
+ * The configuration key of the buffer size for stream.
+ */
+ public static final String CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY =
+ CONF_PREFIX + "stream.buffer.size";
+
+ // stream related configuration keys
+ /**
+ * The default value of the buffer size for stream.
+ */
+ public static final int CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_DEFAULT = 8192;
+
+ // native lib related configuration keys
+ /**
+ * The configuration key of the path for loading crypto library.
+ */
+ public static final String CHIMERA_CRYPTO_LIB_PATH_KEY =
+ CONF_PREFIX + "lib.path";
+
+ /**
+ * The configuration key of the file name for loading crypto library.
+ */
+ public static final String CHIMERA_CRYPTO_LIB_NAME_KEY =
+ CONF_PREFIX + "lib.name";
+
+ /**
+ * The configuration key of temp directory for extracting crypto library.
+ */
+ public static final String CHIMERA_CRYPTO_LIB_TEMPDIR_KEY =
+ CONF_PREFIX + "lib.tempdir";
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/conf/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/conf/package-info.java b/src/main/java/org/apache/commons/crypto/conf/package-info.java
new file mode 100644
index 0000000..837b195
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/conf/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+/**
+ * Configuration classes
+ */
+package org.apache.commons.crypto.conf;
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/random/JavaSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/JavaSecureRandom.java b/src/main/java/org/apache/commons/crypto/random/JavaSecureRandom.java
new file mode 100644
index 0000000..6c079d2
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/JavaSecureRandom.java
@@ -0,0 +1,73 @@
+/**
+ * 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;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.commons.crypto.conf.ConfigurationKeys;
+
+/**
+ * A SecureRandom of Java implementation.
+ */
+public class JavaSecureRandom implements SecureRandom {
+ private static final Log LOG =
+ LogFactory.getLog(JavaSecureRandom.class.getName());
+
+ private java.security.SecureRandom instance;
+
+ /**
+ * Constructs a {@link org.apache.commons.crypto.random.JavaSecureRandom}.
+ *
+ * @param properties the configuration properties.
+ */
+ public JavaSecureRandom(Properties properties) {
+ try {
+ instance = java.security.SecureRandom
+ .getInstance(properties.getProperty(
+ ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_JAVA_ALGORITHM_KEY,
+ ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_JAVA_ALGORITHM_DEFAULT));
+ } catch (NoSuchAlgorithmException e) {
+ LOG.error("Failed to create java secure random due to error: " + e);
+ }
+ }
+
+ /**
+ * Overrides {@link java.lang.AutoCloseable#close()}.
+ * For{@link JavaSecureRandom}, we don't need to recycle resource.
+ */
+ @Override
+ public void close() {
+ // do nothing
+ }
+
+ /**
+ * Overrides {@link org.apache.commons.crypto.random.SecureRandom#nextBytes(byte[])}.
+ * Generates random bytes and places them into a user-supplied byte array.
+ * The number of random bytes produced is equal to the length of the byte array.
+ *
+ * @param bytes the array to be filled in with random bytes.
+ */
+ @Override
+ public void nextBytes(byte[] bytes) {
+ instance.nextBytes(bytes);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/random/OpensslSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OpensslSecureRandom.java b/src/main/java/org/apache/commons/crypto/random/OpensslSecureRandom.java
new file mode 100644
index 0000000..3794fde
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/OpensslSecureRandom.java
@@ -0,0 +1,140 @@
+/**
+ * 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;
+
+import java.util.Properties;
+import java.util.Random;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.commons.crypto.utils.NativeCodeLoader;
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * OpenSSL secure random using JNI.
+ * This implementation is thread-safe.
+ * <p/>
+ *
+ * If using an Intel chipset with RDRAND, the high-performance hardware
+ * random number generator will be used and it's much faster than
+ * {@link java.security.SecureRandom}. If RDRAND is unavailable, default
+ * OpenSSL secure random generator will be used. It's still faster
+ * and can generate strong random bytes.
+ * <p/>
+ * @see https://wiki.openssl.org/index.php/Random_Numbers
+ * @see http://en.wikipedia.org/wiki/RdRand
+ */
+public class OpensslSecureRandom extends Random implements SecureRandom {
+ private static final long serialVersionUID = -7828193502768789584L;
+ private static final Log LOG =
+ LogFactory.getLog(OpensslSecureRandom.class.getName());
+
+ /** If native SecureRandom unavailable, use java SecureRandom */
+ private JavaSecureRandom fallback = null;
+ private static boolean nativeEnabled = false;
+ static {
+ if (NativeCodeLoader.isNativeCodeLoaded()) {
+ try {
+ OpensslSecureRandomNative.initSR();
+ nativeEnabled = true;
+ } catch (Throwable t) {
+ LOG.error("Failed to load Openssl SecureRandom", t);
+ }
+ }
+ }
+
+ /**
+ * Judges whether loading native library successfully.
+ *
+ * @return true if loading library successfully.
+ */
+ public static boolean isNativeCodeLoaded() {
+ return nativeEnabled;
+ }
+
+ /**
+ * Constructs a {@link org.apache.commons.crypto.random.OpensslSecureRandom}.
+ *
+ * @param props the configuration properties.
+ */
+ public OpensslSecureRandom(Properties props) {
+ if (!nativeEnabled) {
+ fallback = new JavaSecureRandom(props);
+ }
+ }
+
+ /**
+ * Generates a user-specified number of random bytes.
+ * It's thread-safe.
+ *
+ * @param bytes the array to be filled in with random bytes.
+ */
+ @Override
+ public void nextBytes(byte[] bytes) {
+ if (!nativeEnabled || !OpensslSecureRandomNative.nextRandBytes(bytes)) {
+ fallback.nextBytes(bytes);
+ }
+ }
+
+ /**
+ * Overrides {@link OpensslSecureRandom}.
+ * For {@link OpensslSecureRandom}, we don't need to set seed.
+ *
+ * @param seed the initial seed.
+ */
+ @Override
+ public void setSeed(long seed) {
+ // Self-seeding.
+ }
+
+ /**
+ * Overrides {@link java.util.Random# next()}. Generates an integer
+ * containing the user-specified number of random
+ * bits(right justified, with leading zeros).
+ *
+ * @param numBits number of random bits to be generated, where
+ * 0 <= <code>numBits</code> <= 32.
+ * @return int an <code>int</code> containing the user-specified number
+ * of random bits (right justified, with leading zeros).
+ */
+ @Override
+ final protected int next(int numBits) {
+ Utils.checkArgument(numBits >= 0 && numBits <= 32);
+ int numBytes = (numBits + 7) / 8;
+ byte b[] = new byte[numBytes];
+ int next = 0;
+
+ nextBytes(b);
+ for (int i = 0; i < numBytes; i++) {
+ next = (next << 8) + (b[i] & 0xFF);
+ }
+
+ return next >>> (numBytes * 8 - numBits);
+ }
+
+ /**
+ * Overrides {@link java.lang.AutoCloseable#close()}. Closes openssl context if native enabled.
+ */
+ @Override
+ public void close() {
+ if (!nativeEnabled && fallback !=null) {
+ fallback.close();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/random/OpensslSecureRandomNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OpensslSecureRandomNative.java b/src/main/java/org/apache/commons/crypto/random/OpensslSecureRandomNative.java
new file mode 100644
index 0000000..d80cf89
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/OpensslSecureRandomNative.java
@@ -0,0 +1,40 @@
+/**
+ * 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 SecureRandom} implementation.
+ * The native method in this class is defined in
+ * OpensslSecureRandomNative.h(genereted by javah).
+ */
+public class OpensslSecureRandomNative {
+ /**
+ * Declares a native method to initialize SR.
+ */
+ public native static void initSR();
+
+ /**
+ * Judges whether use {@link OpensslSecureRandomNative} 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 OpensslSecureRandomNative} 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/4920d272/src/main/java/org/apache/commons/crypto/random/OsSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OsSecureRandom.java b/src/main/java/org/apache/commons/crypto/random/OsSecureRandom.java
new file mode 100644
index 0000000..916ad10
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/OsSecureRandom.java
@@ -0,0 +1,133 @@
+/**
+ * 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;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Random;
+
+import org.apache.commons.crypto.utils.IOUtils;
+import org.apache.commons.crypto.utils.Utils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A Random implementation that uses random bytes sourced from the
+ * operating system.
+ */
+public class OsSecureRandom extends Random implements SecureRandom {
+ public static final Log LOG = LogFactory.getLog(OsSecureRandom.class);
+
+ private static final long serialVersionUID = 6391500337172057900L;
+
+ private final int RESERVOIR_LENGTH = 8192;
+
+ private String randomDevPath;
+
+ private transient FileInputStream stream;
+
+ private final byte[] reservoir = new byte[RESERVOIR_LENGTH];
+
+ private int pos = reservoir.length;
+
+ private void fillReservoir(int min) {
+ if (pos >= reservoir.length - min) {
+ try {
+ IOUtils.readFully(stream, reservoir, 0, reservoir.length);
+ } catch (IOException e) {
+ throw new RuntimeException("failed to fill reservoir", e);
+ }
+ pos = 0;
+ }
+ }
+
+ /**
+ * Constructs a {@link org.apache.commons.crypto.random.OsSecureRandom}.
+ *
+ * @param props the configuration properties.
+ */
+ public OsSecureRandom(Properties props) {
+ randomDevPath = Utils.getRandomDevPath(props);
+ File randomDevFile = new File(randomDevPath);
+
+ try {
+ close();
+ this.stream = new FileInputStream(randomDevFile);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ try {
+ fillReservoir(0);
+ } catch (RuntimeException e) {
+ close();
+ throw e;
+ }
+ }
+
+ /**
+ * Overrides {@link org.apache.commons.crypto.random.SecureRandom#nextBytes(byte[])}.
+ * Generates random bytes and places them into a user-supplied byte array.
+ * The number of random bytes produced is equal to the length of the byte array.
+ *
+ * @param bytes the array to be filled in with random bytes.
+ */
+ @Override
+ synchronized public void nextBytes(byte[] bytes) {
+ int off = 0;
+ int n = 0;
+ while (off < bytes.length) {
+ fillReservoir(0);
+ n = Math.min(bytes.length - off, reservoir.length - pos);
+ System.arraycopy(reservoir, pos, bytes, off, n);
+ off += n;
+ pos += n;
+ }
+ }
+
+ /**
+ * Overrides {@link java.util.Random# next()}. Generates the next pseudorandom number.
+ * Subclasses should override this, as this is used by all other methods.
+ *
+ * @param nbits random bits.
+ * @return the next pseudorandom value from this random number
+ * generator's sequence.
+ */
+ @Override
+ synchronized protected int next(int nbits) {
+ fillReservoir(4);
+ int n = 0;
+ for (int i = 0; i < 4; i++) {
+ n = ((n << 8) | (reservoir[pos++] & 0xff));
+ }
+ return n & (0xffffffff >> (32 - nbits));
+ }
+
+ /**
+ * Overrides {@link java.lang.AutoCloseable#close()}. Closes the OS stream.
+ */
+ @Override
+ synchronized public void close() {
+ if (stream != null) {
+ IOUtils.cleanup(LOG, stream);
+ stream = null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/random/SecureRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/SecureRandom.java b/src/main/java/org/apache/commons/crypto/random/SecureRandom.java
new file mode 100644
index 0000000..69c5559
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/SecureRandom.java
@@ -0,0 +1,36 @@
+/**
+ * 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;
+
+import java.io.Closeable;
+
+/**
+ * The interface for SecureRandom.
+ */
+public interface SecureRandom extends Closeable {
+
+ /**
+ * Generates random bytes and places them into a user-supplied
+ * byte array. The number of random bytes produced is equal to
+ * the length of the byte array.
+ *
+ * @param bytes the byte array to fill with random bytes
+ */
+ void nextBytes(byte[] bytes);
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/random/SecureRandomFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/SecureRandomFactory.java b/src/main/java/org/apache/commons/crypto/random/SecureRandomFactory.java
new file mode 100644
index 0000000..104e5d8
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/SecureRandomFactory.java
@@ -0,0 +1,72 @@
+/**
+ * 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;
+
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.commons.crypto.utils.Utils;
+import org.apache.commons.crypto.utils.ReflectionUtils;
+
+import static org.apache.commons.crypto.conf.ConfigurationKeys
+ .CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY;
+
+/**
+ * This is the factory class used for {@link SecureRandom}.
+ */
+public class SecureRandomFactory {
+ public final static Logger LOG = LoggerFactory
+ .getLogger(SecureRandomFactory.class);
+
+ /**
+ * Gets a SecureRandom instance for specified props.
+ *
+ * @param props the configuration properties.
+ * @return SecureRandom the secureRandom object.Null value will be returned if no
+ * SecureRandom classes with props.
+ */
+ public static SecureRandom getSecureRandom(Properties props) {
+ String secureRandomClasses = props.getProperty(
+ CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY);
+ if (secureRandomClasses == null) {
+ secureRandomClasses = System.getProperty(
+ CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY);
+ }
+
+ SecureRandom random = null;
+ if (secureRandomClasses != null) {
+ for (String klassName : Utils.splitClassNames(secureRandomClasses, ",")) {
+ try {
+ final Class<?> klass = ReflectionUtils.getClassByName(klassName);
+ random = (SecureRandom) ReflectionUtils.newInstance(klass, props);
+ if (random != null) {
+ break;
+ }
+ } catch (ClassCastException e) {
+ LOG.error("Class {} is not a Cipher.", klassName);
+ } catch (ClassNotFoundException e) {
+ LOG.error("Cipher {} not found.", klassName);
+ }
+ }
+ }
+
+ return (random == null) ? new JavaSecureRandom(props) : random;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/random/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/package-info.java b/src/main/java/org/apache/commons/crypto/random/package-info.java
new file mode 100644
index 0000000..f8fd4de
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+/**
+ * Random classes
+ */
+package org.apache.commons.crypto.random;
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/CTRCryptoInputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/CTRCryptoInputStream.java b/src/main/java/org/apache/commons/crypto/stream/CTRCryptoInputStream.java
new file mode 100644
index 0000000..fc76f16
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/CTRCryptoInputStream.java
@@ -0,0 +1,423 @@
+/**
+ * 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.stream;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+import org.apache.commons.crypto.stream.input.ChannelInput;
+import org.apache.commons.crypto.stream.input.Input;
+import org.apache.commons.crypto.stream.input.StreamInput;
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * CTRCryptoInputStream decrypts data. AES CTR mode is required in order to
+ * ensure that the plain text and cipher text have a 1:1 mapping. CTR crypto
+ * stream has stream characteristic which is useful for implement features
+ * like random seek. The decryption is buffer based. The key points of the
+ * decryption are (1) calculating the counter and (2) padding through stream
+ * position:
+ * <p/>
+ * counter = base + pos/(algorithm blocksize);
+ * padding = pos%(algorithm blocksize);
+ * <p/>
+ * The underlying stream offset is maintained as state. It is not thread-safe.
+ */
+public class CTRCryptoInputStream extends CryptoInputStream {
+ /**
+ * Underlying stream offset
+ */
+ protected long streamOffset = 0;
+
+ /**
+ * Padding = pos%(algorithm blocksize); Padding is put into {@link #inBuffer}
+ * before any other data goes in. The purpose of padding is to put the input
+ * data at proper position.
+ */
+ private byte padding;
+
+ /**
+ * Flag to mark whether the cipher has been reset
+ */
+ private boolean cipherReset = false;
+
+ public CTRCryptoInputStream(Properties props, InputStream in,
+ byte[] key, byte[] iv)
+ throws IOException {
+ this(props, in, key, iv, 0);
+ }
+
+ public CTRCryptoInputStream(Properties props, ReadableByteChannel in,
+ byte[] key, byte[] iv)
+ throws IOException {
+ this(props, in, key, iv, 0);
+ }
+
+ public CTRCryptoInputStream(InputStream in, Cipher cipher, int bufferSize,
+ byte[] key, byte[] iv) throws IOException {
+ this(in, cipher, bufferSize, key, iv, 0);
+ }
+
+ public CTRCryptoInputStream(ReadableByteChannel in, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv) throws IOException {
+ this(in, cipher, bufferSize, key, iv, 0);
+ }
+
+ public CTRCryptoInputStream(
+ Input input,
+ Cipher cipher,
+ int bufferSize,
+ byte[] key,
+ byte[] iv) throws IOException {
+ this(input, cipher, bufferSize, key, iv, 0);
+ }
+
+ public CTRCryptoInputStream(Properties props, InputStream in,
+ byte[] key, byte[] iv, long streamOffset)
+ throws IOException {
+ this(in, Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, props),
+ Utils.getBufferSize(props), key, iv, streamOffset);
+ }
+
+ public CTRCryptoInputStream(Properties props, ReadableByteChannel in,
+ byte[] key, byte[] iv, long streamOffset)
+ throws IOException {
+ this(in, Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, props),
+ Utils.getBufferSize(props), key, iv, streamOffset);
+ }
+
+ public CTRCryptoInputStream(InputStream in, Cipher cipher, int bufferSize,
+ byte[] key, byte[] iv, long streamOffset) throws IOException {
+ this(new StreamInput(in, bufferSize), cipher, bufferSize, key, iv, streamOffset);
+ }
+
+ public CTRCryptoInputStream(ReadableByteChannel in, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv, long streamOffset) throws IOException {
+ this(new ChannelInput(in), cipher, bufferSize, key, iv, streamOffset);
+ }
+
+ public CTRCryptoInputStream(
+ Input input,
+ Cipher cipher,
+ int bufferSize,
+ byte[] key,
+ byte[] iv,
+ long streamOffset) throws IOException {
+ super(input, cipher, bufferSize, key, iv);
+
+ Utils.checkStreamCipher(cipher);
+
+ resetStreamOffset(streamOffset);
+ }
+
+ /** Skip n bytes */
+ @Override
+ public long skip(long n) throws IOException {
+ Utils.checkArgument(n >= 0, "Negative skip length.");
+ checkStream();
+
+ if (n == 0) {
+ return 0;
+ } else if (n <= outBuffer.remaining()) {
+ int pos = outBuffer.position() + (int) n;
+ outBuffer.position(pos);
+ return n;
+ } else {
+ /*
+ * Subtract outBuffer.remaining() to see how many bytes we need to
+ * skip in the underlying stream. Add outBuffer.remaining() to the
+ * actual number of skipped bytes in the underlying stream to get the
+ * number of skipped bytes from the user's point of view.
+ */
+ n -= outBuffer.remaining();
+ long skipped = input.skip(n);
+ if (skipped < 0) {
+ skipped = 0;
+ }
+ long pos = streamOffset + skipped;
+ skipped += outBuffer.remaining();
+ resetStreamOffset(pos);
+ return skipped;
+ }
+ }
+
+ /** ByteBuffer read. */
+ @Override
+ public int read(ByteBuffer buf) throws IOException {
+ checkStream();
+ int unread = outBuffer.remaining();
+ if (unread <= 0) { // Fill the unread decrypted data buffer firstly
+ final int n = input.read(inBuffer);
+ if (n <= 0) {
+ return n;
+ }
+
+ streamOffset += n; // Read n bytes
+ if (buf.isDirect() && buf.remaining() >= inBuffer.position() && padding == 0) {
+ // Use buf as the output buffer directly
+ decryptInPlace(buf);
+ padding = postDecryption(streamOffset);
+ return n;
+ } else {
+ // Use outBuffer as the output buffer
+ decrypt();
+ padding = postDecryption(streamOffset);
+ }
+ }
+
+ // Copy decrypted data from outBuffer to buf
+ unread = outBuffer.remaining();
+ final int toRead = buf.remaining();
+ if (toRead <= unread) {
+ final int limit = outBuffer.limit();
+ outBuffer.limit(outBuffer.position() + toRead);
+ buf.put(outBuffer);
+ outBuffer.limit(limit);
+ return toRead;
+ } else {
+ buf.put(outBuffer);
+ return unread;
+ }
+ }
+
+ /**
+ * Seek the stream to a specific position relative to start of the under layer stream.
+ *
+ * @param position The position to seek to
+ * @throws IOException if seek failed
+ */
+ public void seek(long position) throws IOException {
+ Utils.checkArgument(position >= 0, "Cannot seek to negative offset.");
+ checkStream();
+ /*
+ * If data of target pos in the underlying stream has already been read
+ * and decrypted in outBuffer, we just need to re-position outBuffer.
+ */
+ if (position >= getStreamPosition() && position <= getStreamOffset()) {
+ int forward = (int) (position - getStreamPosition());
+ if (forward > 0) {
+ outBuffer.position(outBuffer.position() + forward);
+ }
+ } else {
+ input.seek(position);
+ resetStreamOffset(position);
+ }
+ }
+
+ protected long getStreamOffset() {
+ return streamOffset;
+ }
+
+ protected long getStreamPosition() {
+ return streamOffset - outBuffer.remaining();
+ }
+
+ /**
+ * Decrypt more data by reading the under layer stream. The decrypted data will
+ * be put in the output buffer.
+ *
+ * @return The number of decrypted data. -1 if end of the decrypted stream
+ */
+ protected int decryptMore() throws IOException {
+ int n = input.read(inBuffer);
+ if (n <= 0) {
+ return n;
+ }
+
+ streamOffset += n; // Read n bytes
+ decrypt();
+ padding = postDecryption(streamOffset);
+ return outBuffer.remaining();
+ }
+
+ /**
+ * Do the decryption using inBuffer as input and outBuffer as output.
+ * Upon return, inBuffer is cleared; the decrypted data starts at
+ * outBuffer.position() and ends at outBuffer.limit();
+ */
+ protected void decrypt() throws IOException {
+ Utils.checkState(inBuffer.position() >= padding);
+ if(inBuffer.position() == padding) {
+ // There is no real data in inBuffer.
+ return;
+ }
+
+ inBuffer.flip();
+ outBuffer.clear();
+ decryptBuffer(outBuffer);
+ inBuffer.clear();
+ outBuffer.flip();
+
+ if (padding > 0) {
+ /*
+ * The plain text and cipher text have a 1:1 mapping, they start at the
+ * same position.
+ */
+ outBuffer.position(padding);
+ }
+ }
+
+ /**
+ * Do the decryption using inBuffer as input and buf as output.
+ * Upon return, inBuffer is cleared; the buf's position will be equal to
+ * <i>p</i> <tt>+</tt> <i>n</i> where <i>p</i> is the position before
+ * decryption, <i>n</i> is the number of bytes decrypted.
+ * The buf's limit will not have changed.
+ */
+ protected void decryptInPlace(ByteBuffer buf) throws IOException {
+ Utils.checkState(inBuffer.position() >= padding);
+ Utils.checkState(buf.isDirect());
+ Utils.checkState(buf.remaining() >= inBuffer.position());
+ Utils.checkState(padding == 0);
+
+ if(inBuffer.position() == padding) {
+ // There is no real data in inBuffer.
+ return;
+ }
+ inBuffer.flip();
+ decryptBuffer(buf);
+ inBuffer.clear();
+ }
+
+ /**
+ * Decrypt all data in buf: total n bytes from given start position.
+ * Output is also buf and same start position.
+ * buf.position() and buf.limit() should be unchanged after decryption.
+ */
+ protected void decrypt(ByteBuffer buf, int offset, int len)
+ throws IOException {
+ final int pos = buf.position();
+ final int limit = buf.limit();
+ int n = 0;
+ while (n < len) {
+ buf.position(offset + n);
+ buf.limit(offset + n + Math.min(len - n, inBuffer.remaining()));
+ inBuffer.put(buf);
+ // Do decryption
+ try {
+ decrypt();
+ buf.position(offset + n);
+ buf.limit(limit);
+ n += outBuffer.remaining();
+ buf.put(outBuffer);
+ } finally {
+ padding = postDecryption(streamOffset - (len - n));
+ }
+ }
+ buf.position(pos);
+ }
+
+ /**
+ * This method is executed immediately after decryption. Check whether
+ * cipher should be updated and recalculate padding if needed.
+ */
+ protected byte postDecryption(long position) throws IOException {
+ byte padding = 0;
+ if (cipherReset) {
+ /*
+ * This code is generally not executed since the cipher usually
+ * maintains cipher context (e.g. the counter) internally. However,
+ * some implementations can't maintain context so a re-init is necessary
+ * after each decryption call.
+ */
+ resetCipher(position);
+ padding = getPadding(position);
+ inBuffer.position(padding);
+ }
+ return padding;
+ }
+
+ protected long getCounter(long position) {
+ return position / cipher.getTransformation().getAlgorithmBlockSize();
+ }
+
+ protected byte getPadding(long position) {
+ return (byte)(position % cipher.getTransformation().getAlgorithmBlockSize());
+ }
+
+ /** Initialize the cipher. */
+ @Override
+ protected void initCipher() {
+ // Do nothing for initCipher
+ // Will reset the cipher when reset the stream offset
+ }
+
+ /** Calculate the counter and iv, reset the cipher. */
+ protected void resetCipher(long position)
+ throws IOException {
+ final long counter = getCounter(position);
+ Utils.calculateIV(initIV, counter, iv);
+ try {
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ } catch (InvalidKeyException e) {
+ throw new IOException(e);
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new IOException(e);
+ }
+ cipherReset = false;
+ }
+
+ /**
+ * Reset the underlying stream offset; clear {@link #inBuffer} and
+ * {@link #outBuffer}. This Typically happens during {@link #skip(long)}.
+ */
+ protected void resetStreamOffset(long offset) throws IOException {
+ streamOffset = offset;
+ inBuffer.clear();
+ outBuffer.clear();
+ outBuffer.limit(0);
+ resetCipher(offset);
+ padding = getPadding(offset);
+ inBuffer.position(padding); // Set proper position for input data.
+ }
+
+ protected void decryptBuffer(ByteBuffer out)
+ throws IOException {
+ int inputSize = inBuffer.remaining();
+ try {
+ int n = cipher.update(inBuffer, out);
+ if (n < inputSize) {
+ /**
+ * Typically code will not get here. Cipher#update will consume all
+ * input data and put result in outBuffer.
+ * Cipher#doFinal will reset the cipher context.
+ */
+ cipher.doFinal(inBuffer, out);
+ cipherReset = true;
+ }
+ } catch (ShortBufferException e) {
+ throw new IOException(e);
+ } catch (IllegalBlockSizeException e) {
+ throw new IOException(e);
+ } catch (BadPaddingException e) {
+ throw new IOException(e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/CTRCryptoOutputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/CTRCryptoOutputStream.java b/src/main/java/org/apache/commons/crypto/stream/CTRCryptoOutputStream.java
new file mode 100644
index 0000000..cb282e3
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/CTRCryptoOutputStream.java
@@ -0,0 +1,230 @@
+/**
+ * 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.stream;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+import org.apache.commons.crypto.stream.output.ChannelOutput;
+import org.apache.commons.crypto.stream.output.Output;
+import org.apache.commons.crypto.stream.output.StreamOutput;
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * CTRCryptoOutputStream encrypts data. It is not thread-safe. AES CTR mode is
+ * required in order to ensure that the plain text and cipher text have a 1:1
+ * mapping. The encryption is buffer based. The key points of the encryption are
+ * (1) calculating counter and (2) padding through stream position.
+ * <p/>
+ * counter = base + pos/(algorithm blocksize);
+ * padding = pos%(algorithm blocksize);
+ * <p/>
+ * The underlying stream offset is maintained as state.
+ */
+public class CTRCryptoOutputStream extends CryptoOutputStream {
+ /**
+ * Underlying stream offset.
+ */
+ protected long streamOffset = 0;
+
+ /**
+ * Padding = pos%(algorithm blocksize); Padding is put into {@link #inBuffer}
+ * before any other data goes in. The purpose of padding is to put input data
+ * at proper position.
+ */
+ private byte padding;
+
+ /**
+ * Flag to mark whether the cipher has been reset
+ */
+ private boolean cipherReset = false;
+
+ public CTRCryptoOutputStream(Properties props, OutputStream out,
+ byte[] key, byte[] iv)
+ throws IOException {
+ this(props, out, key, iv, 0);
+ }
+
+ public CTRCryptoOutputStream(Properties props, WritableByteChannel out,
+ byte[] key, byte[] iv)
+ throws IOException {
+ this(props, out, key, iv, 0);
+ }
+
+ public CTRCryptoOutputStream(OutputStream out, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv) throws IOException {
+ this(out, cipher, bufferSize, key, iv, 0);
+ }
+
+ public CTRCryptoOutputStream(WritableByteChannel channel, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv) throws IOException {
+ this(channel, cipher, bufferSize, key, iv, 0);
+ }
+
+ public CTRCryptoOutputStream(Output output, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv)
+ throws IOException {
+ this(output, cipher, bufferSize, key, iv, 0);
+ }
+
+ public CTRCryptoOutputStream(Properties props, OutputStream out,
+ byte[] key, byte[] iv, long streamOffset)
+ throws IOException {
+ this(out, Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, props),
+ Utils.getBufferSize(props), key, iv, streamOffset);
+ }
+
+ public CTRCryptoOutputStream(Properties props, WritableByteChannel out,
+ byte[] key, byte[] iv, long streamOffset)
+ throws IOException {
+ this(out, Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, props),
+ Utils.getBufferSize(props), key, iv, streamOffset);
+ }
+
+ public CTRCryptoOutputStream(OutputStream out, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv, long streamOffset) throws IOException {
+ this(new StreamOutput(out, bufferSize), cipher,
+ bufferSize, key, iv, streamOffset);
+ }
+
+ public CTRCryptoOutputStream(WritableByteChannel channel, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv, long streamOffset) throws IOException {
+ this(new ChannelOutput(channel), cipher,
+ bufferSize, key, iv, streamOffset);
+ }
+
+ public CTRCryptoOutputStream(Output output, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv, long streamOffset)
+ throws IOException {
+ super(output, cipher, bufferSize, key, iv);
+
+ Utils.checkStreamCipher(cipher);
+ this.streamOffset = streamOffset;
+
+ resetCipher();
+ }
+
+ /**
+ * Do the encryption, input is {@link #inBuffer} and output is
+ * {@link #outBuffer}.
+ */
+ @Override
+ protected void encrypt() throws IOException {
+ Utils.checkState(inBuffer.position() >= padding);
+ if (inBuffer.position() == padding) {
+ // There is no real data in the inBuffer.
+ return;
+ }
+
+ inBuffer.flip();
+ outBuffer.clear();
+ encryptBuffer(outBuffer);
+ inBuffer.clear();
+ outBuffer.flip();
+
+ if (padding > 0) {
+ /*
+ * The plain text and cipher text have a 1:1 mapping, they start at the
+ * same position.
+ */
+ outBuffer.position(padding);
+ padding = 0;
+ }
+
+ final int len = output.write(outBuffer);
+ streamOffset += len;
+ if (cipherReset) {
+ /*
+ * This code is generally not executed since the encryptor usually
+ * maintains encryption context (e.g. the counter) internally. However,
+ * some implementations can't maintain context so a re-init is necessary
+ * after each encryption call.
+ */
+ resetCipher();
+ }
+ }
+
+ /**
+ * Do final encryption of the last data
+ */
+ @Override
+ protected void encryptFinal() throws IOException {
+ // The same as the normal encryption for Counter mode
+ encrypt();
+ }
+
+ /** Initialize the cipher. */
+ @Override
+ protected void initCipher() {
+ // Do nothing for initCipher
+ // Will reset the cipher considering the stream offset
+ }
+
+ /** Reset the {@link #cipher}: calculate counter and {@link #padding}. */
+ private void resetCipher() throws IOException {
+ final long counter =
+ streamOffset / cipher.getTransformation().getAlgorithmBlockSize();
+ padding =
+ (byte)(streamOffset % cipher.getTransformation().getAlgorithmBlockSize());
+ inBuffer.position(padding); // Set proper position for input data.
+
+ Utils.calculateIV(initIV, counter, iv);
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+ } catch (InvalidKeyException e) {
+ throw new IOException(e);
+ }catch (InvalidAlgorithmParameterException e) {
+ throw new IOException(e);
+ }
+ cipherReset = false;
+ }
+
+ private void encryptBuffer(ByteBuffer out)
+ throws IOException {
+ int inputSize = inBuffer.remaining();
+ try {
+ int n = cipher.update(inBuffer, out);
+ if (n < inputSize) {
+ /**
+ * Typically code will not get here. Cipher#update will consume all
+ * input data and put result in outBuffer.
+ * Cipher#doFinal will reset the cipher context.
+ */
+ cipher.doFinal(inBuffer, out);
+ cipherReset = true;
+ }
+ } catch (ShortBufferException e) {
+ throw new IOException(e);
+ } catch (BadPaddingException e) {
+ throw new IOException(e);
+ } catch (IllegalBlockSizeException e) {
+ throw new IOException(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/CryptoInputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/CryptoInputStream.java b/src/main/java/org/apache/commons/crypto/stream/CryptoInputStream.java
new file mode 100644
index 0000000..6498273
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/CryptoInputStream.java
@@ -0,0 +1,394 @@
+/**
+ * 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.stream;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+import org.apache.commons.crypto.stream.input.ChannelInput;
+import org.apache.commons.crypto.stream.input.Input;
+import org.apache.commons.crypto.stream.input.StreamInput;
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * CryptoInputStream reads input data and decrypts data in stream manner. It supports
+ * any mode of operations such as AES CBC/CTR/GCM mode in concept.It is not thread-safe.
+ *
+ */
+
+public class CryptoInputStream extends InputStream implements
+ ReadableByteChannel {
+ private final byte[] oneByteBuf = new byte[1];
+
+ protected final Cipher cipher;
+ protected final int bufferSize;
+
+ protected final byte[] key;
+ protected final byte[] initIV;
+ protected byte[] iv;
+
+ protected boolean closed;
+ protected boolean finalDone = false;
+
+ protected Input input;
+
+ /**
+ * Input data buffer. The data starts at inBuffer.position() and ends at
+ * to inBuffer.limit().
+ */
+ protected ByteBuffer inBuffer;
+
+ /**
+ * The decrypted data buffer. The data starts at outBuffer.position() and
+ * ends at outBuffer.limit();
+ */
+ protected ByteBuffer outBuffer;
+
+ public CryptoInputStream(CipherTransformation transformation,
+ Properties props, InputStream in, byte[] key, byte[] iv)
+ throws IOException {
+ this(in, Utils.getCipherInstance(transformation, props),
+ Utils.getBufferSize(props), key, iv);
+ }
+
+ public CryptoInputStream(CipherTransformation transformation,
+ Properties props, ReadableByteChannel in, byte[] key, byte[] iv)
+ throws IOException {
+ this(in, Utils.getCipherInstance(transformation, props),
+ Utils.getBufferSize(props), key, iv);
+ }
+
+ public CryptoInputStream(InputStream in, Cipher cipher, int bufferSize,
+ byte[] key, byte[] iv) throws IOException {
+ this(new StreamInput(in, bufferSize), cipher, bufferSize, key, iv);
+ }
+
+ public CryptoInputStream(ReadableByteChannel in, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv) throws IOException {
+ this(new ChannelInput(in), cipher, bufferSize, key, iv);
+ }
+
+ public CryptoInputStream(
+ Input input,
+ Cipher cipher,
+ int bufferSize,
+ byte[] key,
+ byte[] iv) throws IOException {
+ this.input = input;
+ this.cipher = cipher;
+ this.bufferSize = Utils.checkBufferSize(cipher, bufferSize);
+ this.key = key.clone();
+ this.initIV = iv.clone();
+ this.iv = iv.clone();
+
+ inBuffer = ByteBuffer.allocateDirect(this.bufferSize);
+ outBuffer = ByteBuffer.allocateDirect(this.bufferSize +
+ cipher.getTransformation().getAlgorithmBlockSize());
+ outBuffer.limit(0);
+
+ initCipher();
+ }
+
+ @Override
+ public int read() throws IOException {
+ int n;
+ while ((n = read(oneByteBuf, 0, 1)) == 0) ;
+ return (n == -1) ? -1 : oneByteBuf[0] & 0xff;
+ }
+
+ /**
+ * Decryption is buffer based.
+ * If there is data in {@link #outBuffer}, then read it out of this buffer.
+ * If there is no data in {@link #outBuffer}, then read more from the
+ * underlying stream and do the decryption.
+ * @param b the buffer into which the decrypted data is read.
+ * @param off the buffer offset.
+ * @param len the maximum number of decrypted data bytes to read.
+ * @return int the total number of decrypted data bytes read into the buffer.
+ * @throws IOException
+ */
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ checkStream();
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (off < 0 || len < 0 || len > b.length - off) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ int remaining = outBuffer.remaining();
+ if (remaining > 0) {
+ // Satisfy the read with the existing data
+ int n = Math.min(len, remaining);
+ outBuffer.get(b, off, n);
+ return n;
+ } else {
+ // No data in the out buffer, try read new data and decrypt it
+ int nd = decryptMore();
+ if(nd <= 0)
+ return nd;
+
+ int n = Math.min(len, outBuffer.remaining());
+ outBuffer.get(b, off, n);
+ return n;
+ }
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ Utils.checkArgument(n >= 0, "Negative skip length.");
+ checkStream();
+
+ if (n == 0) {
+ return 0;
+ }
+
+ long remaining = n;
+ int nd;
+
+ while (remaining > 0) {
+ if(remaining <= outBuffer.remaining()) {
+ // Skip in the remaining buffer
+ int pos = outBuffer.position() + (int) remaining;
+ outBuffer.position(pos);
+
+ remaining = 0;
+ break;
+ } else {
+ remaining -= outBuffer.remaining();
+ outBuffer.clear();
+ }
+
+ nd = decryptMore();
+ if (nd < 0) {
+ break;
+ }
+ }
+
+ return n - remaining;
+ }
+
+ @Override
+ public int available() throws IOException {
+ checkStream();
+
+ return input.available() + outBuffer.remaining();
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (closed) {
+ return;
+ }
+
+ input.close();
+ freeBuffers();
+ cipher.close();
+ super.close();
+ closed = true;
+ }
+
+ @Override
+ public void mark(int readlimit) {
+ }
+
+ @Override
+ public void reset() throws IOException {
+ throw new IOException("Mark/reset not supported");
+ }
+
+ @Override
+ public boolean markSupported() {
+ return false;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return !closed;
+ }
+
+ @Override
+ public int read(ByteBuffer dst) throws IOException {
+ checkStream();
+ int remaining = outBuffer.remaining();
+ if (remaining <= 0) {
+ // Decrypt more data
+ int nd = decryptMore();
+ if(nd < 0) {
+ return -1;
+ }
+ }
+
+ // Copy decrypted data from outBuffer to dst
+ remaining = outBuffer.remaining();
+ final int toRead = dst.remaining();
+ if (toRead <= remaining) {
+ final int limit = outBuffer.limit();
+ outBuffer.limit(outBuffer.position() + toRead);
+ dst.put(outBuffer);
+ outBuffer.limit(limit);
+ return toRead;
+ } else {
+ dst.put(outBuffer);
+ return remaining;
+ }
+ }
+
+ /**
+ * Get the buffer size
+ */
+ protected int getBufferSize() {
+ return bufferSize;
+ }
+
+ /**
+ * Get the key
+ */
+ protected byte[] getKey() {
+ return key;
+ }
+
+ /**
+ * Get the initialization vector
+ */
+ protected byte[] getInitIV() {
+ return initIV;
+ }
+
+ /**
+ * Get the internal Cipher
+ */
+ protected Cipher getCipher() {
+ return cipher;
+ }
+
+ /** Initialize the cipher. */
+ protected void initCipher()
+ throws IOException {
+ try {
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ } catch (InvalidKeyException e) {
+ throw new IOException(e);
+ } catch(InvalidAlgorithmParameterException e) {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Decrypt more data by reading the under layer stream. The decrypted data will
+ * be put in the output buffer. If the end of the under stream reached, we will
+ * do final of the cipher to finish all the decrypting of data.
+ *
+ * @return The number of decrypted data. -1 if end of the decrypted stream
+ */
+ protected int decryptMore() throws IOException {
+ if(finalDone) {
+ return -1;
+ }
+
+ int n = input.read(inBuffer);
+ if (n < 0) {
+ // The stream is end, finalize the cipher stream
+ decryptFinal();
+
+ // Satisfy the read with the remaining
+ int remaining = outBuffer.remaining();
+ if (remaining > 0) {
+ return remaining;
+ }
+
+ // End of the stream
+ return -1;
+ } else if(n == 0) {
+ // No data is read, but the stream is not end yet
+ return 0;
+ } else {
+ decrypt();
+ return outBuffer.remaining();
+ }
+ }
+
+ /**
+ * Do the decryption using inBuffer as input and outBuffer as output.
+ * Upon return, inBuffer is cleared; the decrypted data starts at
+ * outBuffer.position() and ends at outBuffer.limit();
+ */
+ protected void decrypt() throws IOException {
+ // Prepare the input buffer and clear the out buffer
+ inBuffer.flip();
+ outBuffer.clear();
+
+ try {
+ cipher.update(inBuffer, outBuffer);
+ } catch (ShortBufferException e) {
+ throw new IOException(e);
+ }
+
+ // Clear the input buffer and prepare out buffer
+ inBuffer.clear();
+ outBuffer.flip();
+ }
+
+ /**
+ * Do final of the cipher to end the decrypting stream
+ */
+ protected void decryptFinal() throws IOException {
+ // Prepare the input buffer and clear the out buffer
+ inBuffer.flip();
+ outBuffer.clear();
+
+ try {
+ cipher.doFinal(inBuffer, outBuffer);
+ finalDone = true;
+ } catch (ShortBufferException e) {
+ throw new IOException(e);
+ } catch (IllegalBlockSizeException e) {
+ throw new IOException(e);
+ } catch( BadPaddingException e) {
+ throw new IOException(e);
+ }
+
+ // Clear the input buffer and prepare out buffer
+ inBuffer.clear();
+ outBuffer.flip();
+ }
+
+ protected void checkStream() throws IOException {
+ if (closed) {
+ throw new IOException("Stream closed");
+ }
+ }
+
+ /** Forcibly free the direct buffers. */
+ protected void freeBuffers() {
+ Utils.freeDirectBuffer(inBuffer);
+ Utils.freeDirectBuffer(outBuffer);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/CryptoOutputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/CryptoOutputStream.java b/src/main/java/org/apache/commons/crypto/stream/CryptoOutputStream.java
new file mode 100644
index 0000000..3d3ac8d
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/CryptoOutputStream.java
@@ -0,0 +1,283 @@
+/**
+ * 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.stream;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+import org.apache.commons.crypto.stream.output.ChannelOutput;
+import org.apache.commons.crypto.stream.output.Output;
+import org.apache.commons.crypto.stream.output.StreamOutput;
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * CryptoOutputStream encrypts data and writes to the under layer output. It supports
+ * any mode of operations such as AES CBC/CTR/GCM mode in concept. It is not thread-safe.
+ */
+
+public class CryptoOutputStream extends OutputStream implements
+ WritableByteChannel {
+ private final byte[] oneByteBuf = new byte[1];
+
+ protected Output output;
+ protected final Cipher cipher;
+ protected final int bufferSize;
+
+ protected final byte[] key;
+ protected final byte[] initIV;
+ protected byte[] iv;
+
+ protected boolean closed;
+
+ /**
+ * Input data buffer. The data starts at inBuffer.position() and ends at
+ * inBuffer.limit().
+ */
+ protected ByteBuffer inBuffer;
+
+ /**
+ * Encrypted data buffer. The data starts at outBuffer.position() and ends at
+ * outBuffer.limit();
+ */
+ protected ByteBuffer outBuffer;
+
+ public CryptoOutputStream(CipherTransformation transformation,
+ Properties props, OutputStream out, byte[] key, byte[] iv)
+ throws IOException {
+ this(out, Utils.getCipherInstance(transformation, props),
+ Utils.getBufferSize(props), key, iv);
+ }
+
+ public CryptoOutputStream(CipherTransformation transformation,
+ Properties props, WritableByteChannel out, byte[] key, byte[] iv)
+ throws IOException {
+ this(out, Utils.getCipherInstance(transformation, props),
+ Utils.getBufferSize(props), key, iv);
+ }
+
+ public CryptoOutputStream(OutputStream out, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv) throws IOException {
+ this(new StreamOutput(out, bufferSize), cipher, bufferSize, key, iv);
+ }
+
+ public CryptoOutputStream(WritableByteChannel channel, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv) throws IOException {
+ this(new ChannelOutput(channel), cipher, bufferSize, key, iv);
+ }
+
+ protected CryptoOutputStream(Output output, Cipher cipher,
+ int bufferSize, byte[] key, byte[] iv)
+ throws IOException {
+
+ this.output = output;
+ this.bufferSize = Utils.checkBufferSize(cipher, bufferSize);
+ this.cipher = cipher;
+ this.key = key.clone();
+ this.initIV = iv.clone();
+ this.iv = iv.clone();
+ inBuffer = ByteBuffer.allocateDirect(this.bufferSize);
+ outBuffer = ByteBuffer.allocateDirect(this.bufferSize +
+ cipher.getTransformation().getAlgorithmBlockSize());
+
+ initCipher();
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ oneByteBuf[0] = (byte)(b & 0xff);
+ write(oneByteBuf, 0, oneByteBuf.length);
+ }
+
+ /**
+ * Encryption is buffer based.
+ * If there is enough room in {@link #inBuffer}, then write to this buffer.
+ * If {@link #inBuffer} is full, then do encryption and write data to the
+ * underlying stream.
+ * @param b the data.
+ * @param off the start offset in the data.
+ * @param len the number of bytes to write.
+ * @throws IOException
+ */
+ public void write(byte[] b, int off, int len) throws IOException {
+ checkStream();
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (off < 0 || len < 0 || off > b.length ||
+ len > b.length - off) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ while (len > 0) {
+ final int remaining = inBuffer.remaining();
+ if (len < remaining) {
+ inBuffer.put(b, off, len);
+ len = 0;
+ } else {
+ inBuffer.put(b, off, remaining);
+ off += remaining;
+ len -= remaining;
+ encrypt();
+ }
+ }
+ }
+
+ /**
+ * To flush, we need to encrypt the data in the buffer and write to the
+ * underlying stream, then do the flush.
+ */
+ @Override
+ public void flush() throws IOException {
+ checkStream();
+ encrypt();
+ output.flush();
+ super.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (closed) {
+ return;
+ }
+
+ try {
+ encryptFinal();
+ output.close();
+ freeBuffers();
+ cipher.close();
+ super.close();
+ } finally {
+ closed = true;
+ }
+ }
+
+ @Override
+ public boolean isOpen() {
+ return !closed;
+ }
+
+ @Override
+ public int write(ByteBuffer src) throws IOException {
+ checkStream();
+ final int len = src.remaining();
+ int remaining = len;
+ while (remaining > 0) {
+ final int space = inBuffer.remaining();
+ if (remaining < space) {
+ inBuffer.put(src);
+ remaining = 0;
+ } else {
+ // to void copy twice, we set the limit to copy directly
+ final int oldLimit = src.limit();
+ final int newLimit = src.position() + space;
+ src.limit(newLimit);
+
+ inBuffer.put(src);
+
+ // restore the old limit
+ src.limit(oldLimit);
+
+ remaining -= space;
+ encrypt();
+ }
+ }
+
+ return len;
+ }
+
+ /** Initialize the cipher. */
+ protected void initCipher()
+ throws IOException {
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+ } catch (InvalidKeyException e) {
+ throw new IOException(e);
+ } catch(InvalidAlgorithmParameterException e) {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Do the encryption, input is {@link #inBuffer} and output is
+ * {@link #outBuffer}.
+ */
+ protected void encrypt() throws IOException {
+
+ inBuffer.flip();
+ outBuffer.clear();
+
+ try {
+ cipher.update(inBuffer, outBuffer);
+ } catch (ShortBufferException e) {
+ throw new IOException(e);
+ }
+
+ inBuffer.clear();
+ outBuffer.flip();
+
+ // write to output
+ output.write(outBuffer);
+ }
+
+ /**
+ * Do final encryption of the last data
+ */
+ protected void encryptFinal() throws IOException {
+ inBuffer.flip();
+ outBuffer.clear();
+
+ try {
+ cipher.doFinal(inBuffer, outBuffer);
+ } catch (ShortBufferException e) {
+ throw new IOException(e);
+ } catch (IllegalBlockSizeException e) {
+ throw new IOException(e);
+ } catch( BadPaddingException e) {
+ throw new IOException(e);
+ }
+
+ inBuffer.clear();
+ outBuffer.flip();
+
+ // write to output
+ output.write(outBuffer);
+ }
+
+ protected void checkStream() throws IOException {
+ if (closed) {
+ throw new IOException("Stream closed");
+ }
+ }
+
+ /** Forcibly free the direct buffers. */
+ protected void freeBuffers() {
+ Utils.freeDirectBuffer(inBuffer);
+ Utils.freeDirectBuffer(outBuffer);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/PositionedCryptoInputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/PositionedCryptoInputStream.java b/src/main/java/org/apache/commons/crypto/stream/PositionedCryptoInputStream.java
new file mode 100644
index 0000000..160f6ee
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/PositionedCryptoInputStream.java
@@ -0,0 +1,311 @@
+/**
+ * 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.stream;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherFactory;
+import org.apache.commons.crypto.stream.input.Input;
+import org.apache.commons.crypto.utils.IOUtils;
+import org.apache.commons.crypto.utils.Utils;
+
+import static org.apache.commons.crypto.cipher.CipherTransformation.AES_CTR_NOPADDING;
+
+/**
+ * PositionedCryptoInputStream provides the capability to decrypt the stream starting
+ * at random position as well as provides the foundation for positioned read for
+ * decrypting. This needs a stream cipher mode such as AES CTR mode.
+ */
+public class PositionedCryptoInputStream extends CTRCryptoInputStream {
+
+ /**
+ * DirectBuffer pool
+ */
+ private final Queue<ByteBuffer> bufferPool = new
+ ConcurrentLinkedQueue<ByteBuffer>();
+
+ /**
+ * Cipher pool
+ */
+ private final Queue<CipherState> cipherPool = new
+ ConcurrentLinkedQueue<CipherState>();
+
+ public PositionedCryptoInputStream(Properties props, Input in,
+ byte[] key, byte[] iv, long streamOffset) throws IOException {
+ this(in, Utils.getCipherInstance(AES_CTR_NOPADDING, props),
+ Utils.getBufferSize(props), key, iv, streamOffset);
+ }
+
+ public PositionedCryptoInputStream(
+ Input input,
+ Cipher cipher,
+ int bufferSize,
+ byte[] key,
+ byte[] iv,
+ long streamOffset) throws IOException {
+ super(input, cipher, bufferSize, key, iv, streamOffset);
+ }
+
+ /**
+ * Read upto the specified number of bytes from a given position
+ * within a stream and return the number of bytes read. This does not
+ * change the current offset of the stream, and is thread-safe.
+ */
+ public int read(long position, byte[] buffer, int offset, int length)
+ throws IOException {
+ checkStream();
+ final int n = input.read(position, buffer, offset, length);
+ if (n > 0) {
+ // This operation does not change the current offset of the file
+ decrypt(position, buffer, offset, n);
+ }
+ return n;
+ }
+
+ /**
+ * Read the specified number of bytes from a given position within a stream.
+ * This does not change the current offset of the stream and is thread-safe.
+ */
+ public void readFully(long position, byte[] buffer, int offset, int length)
+ throws IOException {
+ checkStream();
+ IOUtils.readFully(input, position, buffer, offset, length);
+ if (length > 0) {
+ // This operation does not change the current offset of the file
+ decrypt(position, buffer, offset, length);
+ }
+ }
+
+ public void readFully(long position, byte[] buffer) throws IOException {
+ readFully(position, buffer, 0, buffer.length);
+ }
+
+ /**
+ * Decrypt length bytes in buffer starting at offset. Output is also put
+ * into buffer starting at offset. It is thread-safe.
+ */
+ protected void decrypt(long position, byte[] buffer, int offset, int length)
+ throws IOException {
+ ByteBuffer inBuffer = getBuffer();
+ ByteBuffer outBuffer = getBuffer();
+ CipherState state = null;
+ try {
+ state = getCipherState();
+ byte[] iv = getInitIV().clone();
+ resetCipher(state, position, iv);
+ byte padding = getPadding(position);
+ inBuffer.position(padding); // Set proper position for input data.
+
+ int n = 0;
+ while (n < length) {
+ int toDecrypt = Math.min(length - n, inBuffer.remaining());
+ inBuffer.put(buffer, offset + n, toDecrypt);
+
+ // Do decryption
+ decrypt(state, inBuffer, outBuffer, padding);
+
+ outBuffer.get(buffer, offset + n, toDecrypt);
+ n += toDecrypt;
+ padding = postDecryption(state, inBuffer, position + n, iv);
+ }
+ } finally {
+ returnBuffer(inBuffer);
+ returnBuffer(outBuffer);
+ returnCipherState(state);
+ }
+ }
+
+ /**
+ * Do the decryption using inBuffer as input and outBuffer as output.
+ * Upon return, inBuffer is cleared; the decrypted data starts at
+ * outBuffer.position() and ends at outBuffer.limit();
+ */
+ private void decrypt(CipherState state, ByteBuffer inBuffer,
+ ByteBuffer outBuffer, byte padding) throws IOException {
+ Utils.checkState(inBuffer.position() >= padding);
+ if(inBuffer.position() == padding) {
+ // There is no real data in inBuffer.
+ return;
+ }
+ inBuffer.flip();
+ outBuffer.clear();
+ decryptBuffer(state, inBuffer, outBuffer);
+ inBuffer.clear();
+ outBuffer.flip();
+ if (padding > 0) {
+ /*
+ * The plain text and cipher text have a 1:1 mapping, they start at the
+ * same position.
+ */
+ outBuffer.position(padding);
+ }
+ }
+
+ private void decryptBuffer(CipherState state, ByteBuffer inBuffer, ByteBuffer outBuffer)
+ throws IOException {
+ int inputSize = inBuffer.remaining();
+ try {
+ int n = state.getCipher().update(inBuffer, outBuffer);
+ if (n < inputSize) {
+ /**
+ * Typically code will not get here. Cipher#update will consume all
+ * input data and put result in outBuffer.
+ * Cipher#doFinal will reset the cipher context.
+ */
+ state.getCipher().doFinal(inBuffer, outBuffer);
+ state.reset(true);
+ }
+ } catch (ShortBufferException e) {
+ throw new IOException(e);
+ } catch (IllegalBlockSizeException e) {
+ throw new IOException(e);
+ } catch (BadPaddingException e) {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * This method is executed immediately after decryption. Check whether
+ * cipher should be updated and recalculate padding if needed.
+ */
+ private byte postDecryption(CipherState state, ByteBuffer inBuffer,
+ long position, byte[] iv) throws IOException {
+ byte padding = 0;
+ if (state.isReset()) {
+ /*
+ * This code is generally not executed since the cipher usually
+ * maintains cipher context (e.g. the counter) internally. However,
+ * some implementations can't maintain context so a re-init is necessary
+ * after each decryption call.
+ */
+ resetCipher(state, position, iv);
+ padding = getPadding(position);
+ inBuffer.position(padding);
+ }
+ return padding;
+ }
+
+ /** Calculate the counter and iv, reset the cipher. */
+ private void resetCipher(CipherState state, long position, byte[] iv)
+ throws IOException {
+ final long counter = getCounter(position);
+ Utils.calculateIV(getInitIV(), counter, iv);
+ try {
+ state.getCipher().init(Cipher.DECRYPT_MODE, getKey(), iv);
+ } catch (InvalidKeyException e) {
+ throw new IOException(e);
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new IOException(e);
+ }
+ state.reset(false);
+ }
+
+ /** Get Cipher from pool */
+ private CipherState getCipherState() throws IOException {
+ CipherState state = cipherPool.poll();
+ if (state == null) {
+ Cipher cipher;
+ try {
+ cipher = CipherFactory.getInstance(getCipher().getTransformation(),
+ getCipher().getProperties());
+ } catch (GeneralSecurityException e) {
+ throw new IOException(e);
+ }
+ state = new CipherState(cipher);
+ }
+
+ return state;
+ }
+
+ /** Return Cipher to pool */
+ private void returnCipherState(CipherState state) {
+ if (state != null) {
+ cipherPool.add(state);
+ }
+ }
+
+ /** Get direct buffer from pool */
+ private ByteBuffer getBuffer() {
+ ByteBuffer buffer = bufferPool.poll();
+ if (buffer == null) {
+ buffer = ByteBuffer.allocateDirect(getBufferSize());
+ }
+
+ return buffer;
+ }
+
+ /** Return direct buffer to pool */
+ private void returnBuffer(ByteBuffer buf) {
+ if (buf != null) {
+ buf.clear();
+ bufferPool.add(buf);
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (!isOpen()) {
+ return;
+ }
+
+ cleanBufferPool();
+ super.close();
+ }
+
+ /** Clean direct buffer pool */
+ private void cleanBufferPool() {
+ ByteBuffer buf;
+ while ((buf = bufferPool.poll()) != null) {
+ Utils.freeDirectBuffer(buf);
+ }
+ }
+
+ private class CipherState {
+ private Cipher cipher;
+ private boolean reset;
+
+ public CipherState(Cipher cipher) {
+ this.cipher = cipher;
+ this.reset = false;
+ }
+
+ public Cipher getCipher() {
+ return cipher;
+ }
+
+ public boolean isReset() {
+ return reset;
+ }
+
+ public void reset(boolean reset) {
+ this.reset = reset;
+ }
+ }
+}
[6/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
Posted by xu...@apache.org.
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/output/StreamOutput.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/output/StreamOutput.java b/src/main/java/com/intel/chimera/stream/output/StreamOutput.java
deleted file mode 100644
index fdf0f03..0000000
--- a/src/main/java/com/intel/chimera/stream/output/StreamOutput.java
+++ /dev/null
@@ -1,101 +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 com.intel.chimera.stream.output;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-
-/**
- * The StreamOutput class takes a <code>OutputStream</code> object and wraps it as
- * <code>Output</code> object acceptable by <code>CryptoOutputStream</code> as the output target.
- */
-public class StreamOutput implements Output {
- private byte[] buf;
- private int bufferSize;
- protected OutputStream out;
-
- /**
- * Constructs a {@link com.intel.chimera.stream.output.StreamOutput}.
- *
- * @param out the OutputStream object.
- * @param bufferSize the buffersize.
- */
- public StreamOutput(OutputStream out, int bufferSize) {
- this.out = out;
- this.bufferSize = bufferSize;
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.output.Output#write(ByteBuffer)}.
- * Writes a sequence of bytes to this output from the given buffer.
- *
- * @param src
- * The buffer from which bytes are to be retrieved.
- *
- * @return The number of bytes written, possibly zero.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int write(ByteBuffer src) throws IOException {
- final int len = src.remaining();
- final byte[] buf = getBuf();
-
- int remaining = len;
- while(remaining > 0) {
- final int n = Math.min(remaining, bufferSize);
- src.get(buf, 0, n);
- out.write(buf, 0, n);
- remaining = src.remaining();
- }
-
- return len;
- }
-
- /**
- * Overrides the {@link Output#flush()}.
- * Flushes this output and forces any buffered output bytes
- * to be written out if the under layer output method support.
- *
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void flush() throws IOException {
- out.flush();
- }
-
- /**
- * Overrides the {@link Output#close()}.
- * Closes this output and releases any system resources associated
- * with the under layer output.
- *
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- out.close();
- }
-
- private byte[] getBuf() {
- if (buf == null) {
- buf = new byte[bufferSize];
- }
- return buf;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/IOUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/IOUtils.java b/src/main/java/com/intel/chimera/utils/IOUtils.java
deleted file mode 100644
index 05986fb..0000000
--- a/src/main/java/com/intel/chimera/utils/IOUtils.java
+++ /dev/null
@@ -1,96 +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 com.intel.chimera.utils;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.intel.chimera.stream.input.Input;
-import org.apache.commons.logging.Log;
-
-/**
- * General utility methods for working with IO.
- */
-public class IOUtils {
-
- /**
- * Does the readFully based on the Input read.
- *
- * @param in the input stream of bytes.
- * @param buf the buffer to be read.
- * @param off the start offset in array buffer.
- * @param len the maximum number of bytes to read.
- * @throws IOException if an I/O error occurs.
- */
- public static void readFully(InputStream in, byte buf[],
- int off, int len) throws IOException {
- int toRead = len;
- while (toRead > 0) {
- int ret = in.read(buf, off, toRead);
- if (ret < 0) {
- throw new IOException( "Premature EOF from inputStream");
- }
- toRead -= ret;
- off += ret;
- }
- }
-
- /**
- * Does the readFully based on Input's positioned read.
- * This does not change the current offset of the stream and is thread-safe.
- *
- * @param in the input source.
- * @param position the given position.
- * @param buffer the buffer to be read.
- * @param length the maximum number of bytes to read.
- * @param offset the start offset in array buffer.
- * @throws IOException if an I/O error occurs.
- */
- public static void readFully(Input in, long position,
- byte[] buffer, int offset, int length) throws IOException {
- int nread = 0;
- while (nread < length) {
- int nbytes = in.read(position+nread, buffer, offset+nread, length-nread);
- if (nbytes < 0) {
- throw new IOException("End of stream reached before reading fully.");
- }
- nread += nbytes;
- }
- }
-
- /**
- * Closes the Closeable objects and <b>ignore</b> any {@link IOException} or
- * null pointers. Must only be used for cleanup in exception handlers.
- *
- * @param log the log to record problems to at debug level. Can be null.
- * @param closeables the objects to close.
- */
- public static void cleanup(Log log, java.io.Closeable... closeables) {
- for (java.io.Closeable c : closeables) {
- if (c != null) {
- try {
- c.close();
- } catch(Throwable e) {
- if (log != null && log.isDebugEnabled()) {
- log.debug("Exception in closing " + c, e);
- }
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/NativeCodeLoader.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/NativeCodeLoader.java b/src/main/java/com/intel/chimera/utils/NativeCodeLoader.java
deleted file mode 100644
index 224750a..0000000
--- a/src/main/java/com/intel/chimera/utils/NativeCodeLoader.java
+++ /dev/null
@@ -1,279 +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 com.intel.chimera.utils;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Properties;
-import java.util.UUID;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-/**
- * A helper to load the native code i.e. libchimera.so.
- * This handles the fallback to either the bundled libchimera-Linux-i386-32.so
- * or the default java implementations where appropriate.
- */
-public class NativeCodeLoader {
-
- private static final Log LOG =
- LogFactory.getLog(NativeCodeLoader.class);
-
- private static boolean nativeCodeLoaded = false;
-
- static {
- // Try to load native library and set fallback flag appropriately
- if(LOG.isDebugEnabled()) {
- LOG.debug("Trying to load the custom-built native-chimera library...");
- }
-
- try {
- File nativeLibFile = findNativeLibrary();
- if (nativeLibFile != null) {
- // Load extracted or specified native library.
- System.load(nativeLibFile.getAbsolutePath());
- } else {
- // Load preinstalled library (in the path -Djava.library.path)
- System.loadLibrary("chimera");
- }
- LOG.debug("Loaded the native library");
- nativeCodeLoaded = true;
- } catch (Throwable t) {
- // Ignore failure to load
- if(LOG.isDebugEnabled()) {
- LOG.debug("Failed to load native library with error: " + t);
- LOG.debug("java.library.path=" +
- System.getProperty("java.library.path"));
- }
- }
-
- if (!nativeCodeLoaded) {
- LOG.warn("Unable to load native library for the platform... " +
- "using builtin-java classes where applicable");
- }
- }
-
- static File findNativeLibrary() {
- // Try to load the library in chimera.lib.path */
- String nativeLibraryPath = Utils
- .getLibPath();
- String nativeLibraryName = Utils
- .getLibName();
-
- // Resolve the library file name with a suffix (e.g., dll, .so, etc.)
- if (nativeLibraryName == null)
- nativeLibraryName = System.mapLibraryName("chimera");
-
- if (nativeLibraryPath != null) {
- File nativeLib = new File(nativeLibraryPath,
- nativeLibraryName);
- if (nativeLib.exists())
- return nativeLib;
- }
-
- // Load an OS-dependent native library inside a jar file
- nativeLibraryPath = "/com/intel/chimera/native/"
- + OSInfo.getNativeLibFolderPathForCurrentOS();
- boolean hasNativeLib = hasResource(nativeLibraryPath + "/"
- + nativeLibraryName);
- if(!hasNativeLib) {
- if (OSInfo.getOSName().equals("Mac")) {
- // Fix for openjdk7 for Mac
- String altName = "libchimera.jnilib";
- if (hasResource(nativeLibraryPath + "/" + altName)) {
- nativeLibraryName = altName;
- hasNativeLib = true;
- }
- }
- }
-
- if (!hasNativeLib) {
- String errorMessage = String.format(
- "no native library is found for os.name=%s and os.arch=%s",
- OSInfo.getOSName(), OSInfo.getArchName());
- throw new RuntimeException(errorMessage);
- }
-
- // Temporary folder for the native lib. Use the value of
- // chimera.tempdir or java.io.tmpdir
- String tempFolder = new File(Utils.getTmpDir())
- .getAbsolutePath();
-
- // Extract and load a native library inside the jar file
- return extractLibraryFile(nativeLibraryPath,
- nativeLibraryName, tempFolder);
- }
-
- /**
- * Extracts the specified library file to the target folder.
- *
- * @param libFolderForCurrentOS the library in chimera.lib.path.
- * @param libraryFileName the library name.
- * @param targetFolder Target folder for the native lib. Use the value of
- * chimera.tempdir or java.io.tmpdir.
- * @return the library file.
- */
- private static File extractLibraryFile(String libFolderForCurrentOS,
- String libraryFileName, String targetFolder) {
- String nativeLibraryFilePath = libFolderForCurrentOS + "/"
- + libraryFileName;
-
- // Attach UUID to the native library file to ensure multiple class loaders
- // can read the libchimera multiple times.
- String uuid = UUID.randomUUID().toString();
- String extractedLibFileName = String.format("chimera-%s-%s-%s", getVersion(), uuid,
- libraryFileName);
- File extractedLibFile = new File(targetFolder, extractedLibFileName);
-
- InputStream reader = null;
- try {
- // Extract a native library file into the target directory
- reader = NativeCodeLoader.class.getResourceAsStream(nativeLibraryFilePath);
- FileOutputStream writer = new FileOutputStream(extractedLibFile);
- try {
- byte[] buffer = new byte[8192];
- int bytesRead;
- while ((bytesRead = reader.read(buffer)) != -1) {
- writer.write(buffer, 0, bytesRead);
- }
- } finally {
- // Delete the extracted lib file on JVM exit.
- extractedLibFile.deleteOnExit();
-
- if (writer != null){
- writer.close();
- }
-
- if (reader != null) {
- reader.close();
- reader = null;
- }
- }
-
- // Set executable (x) flag to enable Java to load the native library
- if (!extractedLibFile.setReadable(true) || !extractedLibFile.setExecutable(true)
- || !extractedLibFile.setWritable(true, true)) {
- throw new RuntimeException("Invalid path for library path");
- }
-
- // Check whether the contents are properly copied from the resource folder
- {
- InputStream nativeIn = null;
- InputStream extractedLibIn = null;
- try {
- nativeIn =
- NativeCodeLoader.class.getResourceAsStream(nativeLibraryFilePath);
- extractedLibIn = new FileInputStream(extractedLibFile);
- if (!contentsEquals(nativeIn, extractedLibIn))
- throw new RuntimeException(String.format(
- "Failed to write a native library file at %s",
- extractedLibFile));
- } finally {
- if (nativeIn != null)
- nativeIn.close();
- if (extractedLibIn != null)
- extractedLibIn.close();
- }
- }
-
- return new File(targetFolder, extractedLibFileName);
- } catch (IOException e) {
- e.printStackTrace(System.err);
- return null;
- } finally{
- if(reader != null){
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- /**
- * Gets the version by reading pom.properties embedded in jar.
- * This version data is used as a suffix of a dll file extracted from the
- * jar.
- *
- * @return the version string
- */
- public static String getVersion() {
- URL versionFile = NativeCodeLoader.class
- .getResource("/META-INF/maven/com.intel.chimera/chimera/pom.properties");
- if (versionFile == null)
- versionFile = NativeCodeLoader.class
- .getResource("/com/intel/chimera/VERSION");
-
- String version = "unknown";
- try {
- if (versionFile != null) {
- Properties versionData = new Properties();
- versionData.load(versionFile.openStream());
- version = versionData.getProperty("version", version);
- if (version.equals("unknown"))
- version = versionData.getProperty("VERSION", version);
- version = version.trim().replaceAll("[^0-9M\\.]", "");
- }
- } catch (IOException e) {
- System.err.println(e);
- }
- return version;
- }
-
- private static boolean contentsEquals(InputStream in1, InputStream in2)
- throws IOException {
- if (!(in1 instanceof BufferedInputStream)) {
- in1 = new BufferedInputStream(in1);
- }
- if (!(in2 instanceof BufferedInputStream)) {
- in2 = new BufferedInputStream(in2);
- }
-
- int ch = in1.read();
- while (ch != -1) {
- int ch2 = in2.read();
- if (ch != ch2)
- return false;
- ch = in1.read();
- }
- int ch2 = in2.read();
- return ch2 == -1;
- }
-
- private static boolean hasResource(String path) {
- return NativeCodeLoader.class.getResource(path) != null;
- }
-
- /**
- * Checks whether native code is loaded for this platform.
- *
- * @return <code>true</code> if native is loaded,
- * else <code>false</code>.
- */
- public static boolean isNativeCodeLoaded() {
- return nativeCodeLoaded;
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/OSInfo.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/OSInfo.java b/src/main/java/com/intel/chimera/utils/OSInfo.java
deleted file mode 100644
index c979599..0000000
--- a/src/main/java/com/intel/chimera/utils/OSInfo.java
+++ /dev/null
@@ -1,190 +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 com.intel.chimera.utils;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Locale;
-
-/**
- * Provides OS name and architecture name.
- */
-public class OSInfo {
- private static HashMap<String, String> archMapping = new HashMap<String, String>();
-
- /**
- * The constant string represents for X86 architecture, the value is: {@value #X86}.*/
- public static final String X86 = "x86";
-
- /**
- * The constant string represents for X86_64 architecture, the value is:{@value #X86_64}.*/
- public static final String X86_64 = "x86_64";
-
- /**
- * The constant string represents for IA64_32 architecture, the value is:{@value #IA64_32}.*/
- public static final String IA64_32 = "ia64_32";
-
- /**
- * The constant string represents for IA64 architecture, the value is:{@value #IA64}.*/
- public static final String IA64 = "ia64";
-
- /**
- * The constant string represents for PPC architecture, the value is:{@value #PPC}.*/
- public static final String PPC = "ppc";
-
- /**
- * The constant string represents for PPC64 architecture, the value is:{@value #PPC64}.*/
- public static final String PPC64 = "ppc64";
-
- static {
- // x86 mappings
- archMapping.put(X86, X86);
- archMapping.put("i386", X86);
- archMapping.put("i486", X86);
- archMapping.put("i586", X86);
- archMapping.put("i686", X86);
- archMapping.put("pentium", X86);
-
- // x86_64 mappings
- archMapping.put(X86_64, X86_64);
- archMapping.put("amd64", X86_64);
- archMapping.put("em64t", X86_64);
- archMapping.put("universal", X86_64); // Needed for openjdk7 in Mac
-
- // Itenium 64-bit mappings
- archMapping.put(IA64, IA64);
- archMapping.put("ia64w", IA64);
-
- // Itenium 32-bit mappings, usually an HP-UX construct
- archMapping.put(IA64_32, IA64_32);
- archMapping.put("ia64n", IA64_32);
-
- // PowerPC mappings
- archMapping.put(PPC, PPC);
- archMapping.put("power", PPC);
- archMapping.put("powerpc", PPC);
- archMapping.put("power_pc", PPC);
- archMapping.put("power_rs", PPC);
-
- // TODO: PowerPC 64bit mappings
- archMapping.put(PPC64, PPC64);
- archMapping.put("power64", PPC64);
- archMapping.put("powerpc64", PPC64);
- archMapping.put("power_pc64", PPC64);
- archMapping.put("power_rs64", PPC64);
- }
-
- public static void main(String[] args) {
- if (args.length >= 1) {
- if ("--os".equals(args[0])) {
- System.out.print(getOSName());
- return;
- } else if ("--arch".equals(args[0])) {
- System.out.print(getArchName());
- return;
- }
- }
-
- System.out.print(getNativeLibFolderPathForCurrentOS());
- }
-
- /**
- * Gets the native lib folder.
- *
- * @return the current OS's native lib folder.
- */
- public static String getNativeLibFolderPathForCurrentOS() {
- return getOSName() + "/" + getArchName();
- }
-
- /**
- * Gets the OS name.
- *
- * @return the OS name.
- */
- public static String getOSName() {
- return translateOSNameToFolderName(System.getProperty("os.name"));
- }
-
- /**
- * Gets the architecture name.
- *
- * @return the architecture name.
- */
- public static String getArchName() {
- // if running Linux on ARM, need to determine ABI of JVM
- String osArch = System.getProperty("os.arch");
- if (osArch.startsWith("arm")
- && System.getProperty("os.name").contains("Linux")) {
- String javaHome = System.getProperty("java.home");
- try {
- // determine if first JVM found uses ARM hard-float ABI
- String[] cmdarray = {
- "/bin/sh",
- "-c",
- "find '" + javaHome
- + "' -name 'libjvm.so' | head -1 | xargs readelf -A | "
- + "grep 'Tag_ABI_VFP_args: VFP registers'" };
- int exitCode = Runtime.getRuntime().exec(cmdarray).waitFor();
- if (exitCode == 0)
- return "armhf";
- } catch (IOException e) {
- // ignored: fall back to "arm" arch (soft-float ABI)
- } catch (InterruptedException e) {
- // ignored: fall back to "arm" arch (soft-float ABI)
- }
- } else {
- String lc = osArch.toLowerCase(Locale.US);
- if (archMapping.containsKey(lc))
- return archMapping.get(lc);
- }
- return translateArchNameToFolderName(osArch);
- }
-
- /**
- * Translates the OS name to folder name.
- *
- * @param osName the OS name.
- * @return the folder name.
- */
- static String translateOSNameToFolderName(String osName) {
- if (osName.contains("Windows")) {
- return "Windows";
- } else if (osName.contains("Mac")) {
- return "Mac";
- } else if (osName.contains("Linux")) {
- return "Linux";
- } else if (osName.contains("AIX")) {
- return "AIX";
- }
-
- else {
- return osName.replaceAll("\\W", "");
- }
- }
-
- /**
- * Translates the architecture name to folder name.
- *
- * @param archName the architecture name.
- * @return the folder name.
- */
- static String translateArchNameToFolderName(String archName) {
- return archName.replaceAll("\\W", "");
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/ReflectionUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/ReflectionUtils.java b/src/main/java/com/intel/chimera/utils/ReflectionUtils.java
deleted file mode 100644
index d40937a..0000000
--- a/src/main/java/com/intel/chimera/utils/ReflectionUtils.java
+++ /dev/null
@@ -1,204 +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 com.intel.chimera.utils;
-
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.util.Collections;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import com.intel.chimera.cipher.Cipher;
-
-/**
- * General utility methods for working with reflection.
- */
-public class ReflectionUtils {
-
- private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>>
- CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();
-
- private static ClassLoader classLoader;
- static {
- classLoader = Thread.currentThread().getContextClassLoader();
- if (classLoader == null) {
- classLoader = Cipher.class.getClassLoader();
- }
- }
-
- /**
- * Sentinel value to store negative cache results in {@link #CACHE_CLASSES}.
- */
- private static final Class<?> NEGATIVE_CACHE_SENTINEL =
- NegativeCacheSentinel.class;
-
- /**
- * A unique class which is used as a sentinel value in the caching
- * for getClassByName. {@link Cipher#getClassByNameOrNull(String)}.
- */
- private static abstract class NegativeCacheSentinel {}
-
- /**
- * Uses the constructor represented by this {@code Constructor} object to
- * create and initialize a new instance of the constructor's
- * declaring class, with the specified initialization parameters.
- *
- * @param klass the Class object.
- * @param args array of objects to be passed as arguments to
- * the constructor call.
- * @return a new object created by calling the constructor
- * this object represents.
- */
- @SuppressWarnings("rawtypes")
- public static <T> T newInstance(Class<T> klass, Object ... args) {
- try {
- Constructor<T> ctor = null;
-
- if (args.length == 0) {
- ctor = klass.getDeclaredConstructor(new Class[] {});
- } else {
- Class[] argClses = new Class[args.length];
- for (int i = 0; i < args.length; i++) {
- argClses[i] = args[i].getClass();
- }
- ctor = klass.getDeclaredConstructor(argClses);
- }
- ctor.setAccessible(true);
- return ctor.newInstance(args);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Gets the value of the <code>name</code> property as a <code>Class</code>
- * implementing the interface specified by <code>xface</code>.
- * If no such property is specified, then <code>defaultValue</code> is
- * returned.An exception is thrown if the returned class does not
- * implement the named interface.
- *
- * @param name the class name of default implementation.
- * @param defaultValue default value.
- * @param xface the interface implemented by the named class.
- * @return property value as a <code>Class</code>,
- * or <code>defaultValue</code>.
- */
- public static <U> Class<? extends U> getClass(String name,
- Class<? extends U> defaultValue,
- Class<U> xface) {
- try {
- Class<?> theClass = null;
- if (name != null && !name.isEmpty()) {
- theClass = getClassByName(name);
- }
- if (theClass == null) {
- theClass = defaultValue;
- }
- if (theClass != null && !xface.isAssignableFrom(theClass))
- throw new RuntimeException(theClass+" not "+xface.getName());
- else if (theClass != null)
- return theClass.asSubclass(xface);
- else
- return null;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Gets the value of the <code>name</code> property as a <code>Class</code>.
- * If no such property is specified, then <code>defaultValue</code> is
- * returned.
- *
- * @param name the class name.
- * @param defaultValue default value.
- * @return property value as a <code>Class</code>,
- * or <code>defaultValue</code>.
- */
- public static Class<?> getClass(String name, Class<?> defaultValue) {
- String valueString = System.getProperty(name);
- if (valueString == null)
- return defaultValue;
- try {
- return getClassByName(valueString);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Loads a class by name.
- *
- * @param name the class name.
- * @return the class object.
- * @throws ClassNotFoundException if the class is not found.
- */
- public static Class<?> getClassByName(String name)
- throws ClassNotFoundException {
- Class<?> ret = getClassByNameOrNull(name);
- if (ret == null) {
- throw new ClassNotFoundException("Class " + name + " not found");
- }
- return ret;
- }
-
- /**
- * Loads a class by name, returning null rather than throwing an exception
- * if it couldn't be loaded. This is to avoid the overhead of creating
- * an exception.
- *
- * @param name the class name.
- * @return the class object, or null if it could not be found.
- */
- private static Class<?> getClassByNameOrNull(String name) {
- Map<String, WeakReference<Class<?>>> map;
-
- synchronized (CACHE_CLASSES) {
- map = CACHE_CLASSES.get(classLoader);
- if (map == null) {
- map = Collections.synchronizedMap(
- new WeakHashMap<String, WeakReference<Class<?>>>());
- CACHE_CLASSES.put(classLoader, map);
- }
- }
-
- Class<?> clazz = null;
- WeakReference<Class<?>> ref = map.get(name);
- if (ref != null) {
- clazz = ref.get();
- }
-
- if (clazz == null) {
- try {
- clazz = Class.forName(name, true, classLoader);
- } catch (ClassNotFoundException e) {
- // Leave a marker that the class isn't found
- map.put(name, new WeakReference<Class<?>>(NEGATIVE_CACHE_SENTINEL));
- return null;
- }
- // two putters can race here, but they'll put the same class
- map.put(name, new WeakReference<Class<?>>(clazz));
- return clazz;
- } else if (clazz == NEGATIVE_CACHE_SENTINEL) {
- return null; // not found
- } else {
- // cache hit
- return clazz;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/Utils.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/Utils.java b/src/main/java/com/intel/chimera/utils/Utils.java
deleted file mode 100644
index ae0eecc..0000000
--- a/src/main/java/com/intel/chimera/utils/Utils.java
+++ /dev/null
@@ -1,362 +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 com.intel.chimera.utils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherFactory;
-import com.intel.chimera.cipher.CipherTransformation;
-
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_DEFAULT;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_DEFAULT;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_NAME_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_PATH_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_SYSTEM_PROPERTIES_FILE;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_TEMPDIR_KEY;
-
-/**
- * General utility methods.
- */
-public class Utils {
- private static final int MIN_BUFFER_SIZE = 512;
-
- protected static final CipherTransformation AES_CTR_NOPADDING = CipherTransformation.AES_CTR_NOPADDING;
-
- /**
- * For AES, the algorithm block is fixed size of 128 bits.
- * @see http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
- */
- private static final int AES_BLOCK_SIZE = AES_CTR_NOPADDING.getAlgorithmBlockSize();
-
- static {
- loadChimeraSystemProperties();
- }
-
- /**
- * loads system properties when configuration file of the name
- * {@link #CHIMERA_SYSTEM_PROPERTIES_FILE} is found.
- */
- private static void loadChimeraSystemProperties() {
- try {
- InputStream is = Thread.currentThread().getContextClassLoader()
- .getResourceAsStream(CHIMERA_SYSTEM_PROPERTIES_FILE);
-
- if (is == null)
- return; // no configuration file is found
-
- // Load property file
- Properties props = new Properties();
- props.load(is);
- is.close();
- Enumeration<?> names = props.propertyNames();
- while (names.hasMoreElements()) {
- String name = (String) names.nextElement();
- if (name.startsWith("chimera.")) {
- if (System.getProperty(name) == null) {
- System.setProperty(name, props.getProperty(name));
- }
- }
- }
- } catch (Throwable ex) {
- System.err.println("Could not load '"
- + CHIMERA_SYSTEM_PROPERTIES_FILE + "' from classpath: "
- + ex.toString());
- }
- }
-
- /**
- * Forcibly free the direct buffer.
- *
- * @param buffer the bytebuffer to be freed.
- */
- public static void freeDirectBuffer(ByteBuffer buffer) {
- if (buffer instanceof sun.nio.ch.DirectBuffer) {
- final sun.misc.Cleaner bufferCleaner =
- ((sun.nio.ch.DirectBuffer) buffer).cleaner();
- bufferCleaner.clean();
- }
- }
-
- /**
- * Reads crypto buffer size.
- *
- * @param props The <code>Properties</code> class represents a set of
- * properties.
- * @return the buffer size.
- * */
- public static int getBufferSize(Properties props) {
- String bufferSizeStr = props.getProperty(
- CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY);
- if (bufferSizeStr == null || bufferSizeStr.isEmpty()) {
- bufferSizeStr = System
- .getProperty(CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY);
- }
- if (bufferSizeStr == null || bufferSizeStr.isEmpty()) {
- return CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_DEFAULT;
- } else {
- return Integer.parseInt(bufferSizeStr);
- }
- }
-
- /**
- * Gets the cipher class.
- *
- * @param props The <code>Properties</code> class represents a set of
- * properties.
- * @return the cipher class based on the props.
- */
- public static String getCipherClassString(Properties props) {
- final String configName = CHIMERA_CRYPTO_CIPHER_CLASSES_KEY;
- return props.getProperty(configName) != null ? props.getProperty(configName) : System
- .getProperty(configName, CHIMERA_CRYPTO_CIPHER_CLASSES_DEFAULT);
- }
-
- /**
- * Gets the Jce provider.
- *
- * @param props The <code>Properties</code> class represents a set of
- * properties.
- * @return the jce provider based on the props.
- */
- public static String getJCEProvider(Properties props) {
- return props.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY) != null ?
- props.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY) :
- System.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY);
- }
-
- /**
- * Gets the random device path.
- *
- * @param props The <code>Properties</code> class represents a set of
- * properties.
- * @return the random device path based on the props.
- */
- public static String getRandomDevPath(Properties props) {
- String devPath = props.getProperty(
- CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY);
- if (devPath == null) {
- devPath = System.getProperty(
- CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY,
- CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT);
- }
- return devPath;
- }
-
- /**
- * Gets path of native library.
- *
- * @return the path of native library.
- */
- public static String getLibPath() {
- return System.getProperty(CHIMERA_CRYPTO_LIB_PATH_KEY);
- }
-
- /**
- * Gets the file name of native library.
- *
- * @return the file name of native library.
- */
- public static String getLibName() {
- return System.getProperty(CHIMERA_CRYPTO_LIB_NAME_KEY);
- }
-
- /**
- * Gets the temp directory for extracting crypto library.
- *
- * @return the temp directory.
- */
- public static String getTmpDir() {
- return System.getProperty(CHIMERA_CRYPTO_LIB_TEMPDIR_KEY,
- System.getProperty("java.io.tmpdir"));
- }
-
- /**
- * Checks whether the cipher is supported streaming.
- *
- * @param cipher the {@link com.intel.chimera.cipher.Cipher} instance.
- * @throws IOException if an I/O error occurs.
- */
- public static void checkStreamCipher(Cipher cipher) throws IOException {
- if (cipher.getTransformation() != CipherTransformation.AES_CTR_NOPADDING) {
- throw new IOException("AES/CTR/NoPadding is required");
- }
- }
-
- /**
- * Checks and floors buffer size.
- *
- * @param cipher the {@link com.intel.chimera.cipher.Cipher} instance.
- * @param bufferSize the buffer size.
- * @return the remaining buffer size.
- */
- public static int checkBufferSize(Cipher cipher, int bufferSize) {
- checkArgument(bufferSize >= MIN_BUFFER_SIZE,
- "Minimum value of buffer size is " + MIN_BUFFER_SIZE + ".");
- return bufferSize - bufferSize % cipher.getTransformation()
- .getAlgorithmBlockSize();
- }
-
- /**
- * This method is only for Counter (CTR) mode. Generally the Cipher calculates the
- * IV and maintain encryption context internally.For example a
- * {@link javax.crypto.Cipher} will maintain its encryption context internally
- * when we do encryption/decryption using the Cipher#update interface.
- * <p/>
- * Encryption/Decryption is not always on the entire file. For example,
- * in Hadoop, a node may only decrypt a portion of a file (i.e. a split).
- * In these situations, the counter is derived from the file position.
- * <p/>
- * The IV can be calculated by combining the initial IV and the counter with
- * a lossless operation (concatenation, addition, or XOR).
- * @see http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29
- *
- * @param initIV initial IV
- * @param counter counter for input stream position
- * @param IV the IV for input stream position
- */
- public static void calculateIV(byte[] initIV, long counter, byte[] IV) {
- checkArgument(initIV.length == AES_BLOCK_SIZE);
- checkArgument(IV.length == AES_BLOCK_SIZE);
-
- int i = IV.length; // IV length
- int j = 0; // counter bytes index
- int sum = 0;
- while (i-- > 0) {
- // (sum >>> Byte.SIZE) is the carry for addition
- sum = (initIV[i] & 0xff) + (sum >>> Byte.SIZE);
- if (j++ < 8) { // Big-endian, and long is 8 bytes length
- sum += (byte) counter & 0xff;
- counter >>>= 8;
- }
- IV[i] = (byte) sum;
- }
- }
-
- /**
- * Helper method to create a Cipher instance and throws only IOException.
- *
- * @param props The <code>Properties</code> class represents a set of
- * properties.
- * @param transformation the CipherTransformation instance.
- * @return the Cipher instance.
- * @throws IOException if an I/O error occurs.
- */
- public static Cipher getCipherInstance(CipherTransformation transformation,
- Properties props) throws IOException {
- try {
- return CipherFactory.getInstance(transformation, props);
- } catch (GeneralSecurityException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Ensures the truth of an expression involving one or more parameters to
- * the calling method.
- *
- * @param expression a boolean expression.
- * @throws IllegalArgumentException if expression is false.
- */
- public static void checkArgument(boolean expression) {
- if(!expression) {
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * Checks the truth of an expression.
- *
- * @param expression a boolean expression.
- * @param errorMessage the exception message to use if the check fails;
- * will be converted to a string using <code>String
- * .valueOf(Object)</code>.
- * @throws IllegalArgumentException if expression is false.
- */
- public static void checkArgument(boolean expression, Object errorMessage) {
- if (!expression) {
- throw new IllegalArgumentException(String.valueOf(errorMessage));
- }
- }
-
- /**
- * Ensures that an object reference passed as a parameter to the calling
- * method is not null.
- *
- * @param reference an object reference.
- * @return the non-null reference that was validated.
- * @throws NullPointerException if reference is null.
- */
- public static <T> T checkNotNull(T reference) {
- if(reference == null) {
- throw new NullPointerException();
- } else {
- return reference;
- }
- }
-
- /**
- * Ensures the truth of an expression involving the state of the calling
- * instance, but not involving any parameters to the calling method.
- *
- * @param expression a boolean expression.
- * @throws IllegalStateException if expression is false.
- */
- public static void checkState(boolean expression) {
- if(!expression) {
- throw new IllegalStateException();
- }
- }
-
- /**
- * Splits class names sequence into substrings, Trim each substring into an
- * entry,and returns an list of the entries.
- *
- * @param clazzNames a string consist of a list of the entries joined by a
- * delimiter.
- * @param separator a delimiter for the input string.
- * @return a list of class entries.
- */
- public static List<String> splitClassNames(String clazzNames,
- String separator) {
- List<String> res = new ArrayList<String>();
- if (clazzNames == null || clazzNames.isEmpty()) {
- return res;
- }
-
- for (String clazzName : clazzNames.split(separator)) {
- clazzName = clazzName.trim();
- if (!clazzName.isEmpty()) {
- res.add(clazzName);
- }
- }
- return res;
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/package-info.java b/src/main/java/com/intel/chimera/utils/package-info.java
deleted file mode 100644
index d1d9483..0000000
--- a/src/main/java/com/intel/chimera/utils/package-info.java
+++ /dev/null
@@ -1,21 +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.
- */
-/**
- * Utils classes
- */
-package com.intel.chimera.utils;
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/VERSION
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/VERSION b/src/main/java/org/apache/commons/crypto/VERSION
new file mode 100644
index 0000000..baca170
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/VERSION
@@ -0,0 +1 @@
+VERSION=1.0.0-SNAPSHOT
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/Cipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/Cipher.java b/src/main/java/org/apache/commons/crypto/cipher/Cipher.java
new file mode 100644
index 0000000..5f0f42b
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/Cipher.java
@@ -0,0 +1,155 @@
+/**
+ * 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.io.Closeable;
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+/**
+ * The interface of cryptographic cipher for encryption and decryption.
+ */
+public interface Cipher extends Closeable {
+
+ /**
+ * A constant representing encrypt mode. The mode constant to be used
+ * when calling init method of the Cipher.
+ */
+ int ENCRYPT_MODE = 1;
+
+ /**
+ * A constant representing decrypt mode. The mode constant to be used
+ * when calling init method of the Cipher.
+ */
+ int DECRYPT_MODE = 0;
+
+ /**
+ * Gets the CipherTransformation for this cipher.
+ *
+ * @return the CipherTransformation for this cipher.
+ */
+ CipherTransformation getTransformation();
+
+ /**
+ * Gets the properties for this cipher.
+ *
+ * @return the properties for this cipher.
+ */
+ Properties getProperties();
+
+ /**
+ * Initializes the cipher with mode, key and iv.
+ *
+ * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
+ * @param key crypto key for the cipher
+ * @param iv Initialization vector for the cipher
+ * @throws InvalidKeyException if the given key is inappropriate for
+ * initializing this cipher, or its keysize exceeds the maximum allowable
+ * keysize (as determined from the configured jurisdiction policy files).
+ * @throws InvalidAlgorithmParameterException if the given algorithm
+ * parameters are inappropriate for this cipher, or this cipher requires
+ * algorithm parameters and <code>params</code> is null, or the given
+ * algorithm parameters imply a cryptographic strength that would exceed
+ * the legal limits (as determined from the configured jurisdiction
+ * policy files).
+ */
+ void init(int mode, byte[] key, byte[] iv)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data
+ * is encrypted or decrypted, depending on how this cipher was initialized.
+ *
+ * @param inBuffer the input ByteBuffer
+ * @param outBuffer the output ByteBuffer
+ * @return int number of bytes stored in <code>output</code>
+ * @throws ShortBufferException if there is insufficient space
+ * in the output buffer
+ */
+ int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
+ throws ShortBufferException;
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data
+ * is encrypted or decrypted, depending on how this cipher was initialized.
+ *
+ * @param input the input byte array
+ * @param inputOffset the offset in input where the input starts
+ * @param inputLen the input length
+ * @param output the byte array for the result
+ * @param outputOffset the offset in output where the result is stored
+ * @return the number of bytes stored in output
+ * @throws ShortBufferException if there is insufficient space in the output byte array
+ */
+ int update(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException;
+
+ /**
+ * Encrypts or decrypts data in a single-part operation, or finishes a
+ * multiple-part operation.
+ *
+ * @param inBuffer the input ByteBuffer
+ * @param outBuffer the output ByteBuffer
+ * @return int number of bytes stored in <code>output</code>
+ * @throws BadPaddingException if this cipher is in decryption mode,
+ * and (un)padding has been requested, but the decrypted data is not
+ * bounded by the appropriate padding bytes
+ * @throws IllegalBlockSizeException if this cipher is a block cipher,
+ * no padding has been requested (only in encryption mode), and the total
+ * input length of the data processed by this cipher is not a multiple of
+ * block size; or if this encryption algorithm is unable to
+ * process the input data provided.
+ * @throws ShortBufferException if the given output buffer is too small
+ * to hold the result
+ */
+ int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException;
+
+ /**
+ * Encrypts or decrypts data in a single-part operation, or finishes a
+ * multiple-part operation.
+ *
+ * @param input the input byte array
+ * @param inputOffset the offset in input where the input starts
+ * @param inputLen the input length
+ * @param output the byte array for the result
+ * @param outputOffset the offset in output where the result is stored
+ * @return the number of bytes stored in output
+ * @throws ShortBufferException if the given output byte array is too small
+ * to hold the result
+ * @throws BadPaddingException if this cipher is in decryption mode,
+ * and (un)padding has been requested, but the decrypted data is not
+ * bounded by the appropriate padding bytes
+ * @throws IllegalBlockSizeException if this cipher is a block cipher,
+ * no padding has been requested (only in encryption mode), and the total
+ * input length of the data processed by this cipher is not a multiple of
+ * block size; or if this encryption algorithm is unable to
+ * process the input data provided.
+ */
+ int doFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException, IllegalBlockSizeException, BadPaddingException;
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/CipherFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/CipherFactory.java b/src/main/java/org/apache/commons/crypto/cipher/CipherFactory.java
new file mode 100644
index 0000000..c8272a6
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/CipherFactory.java
@@ -0,0 +1,105 @@
+/**
+ * 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.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.crypto.utils.ReflectionUtils;
+import org.apache.commons.crypto.utils.Utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the factory class used for creating cipher class
+ */
+public class CipherFactory {
+
+ /** LOG instance for {@CipherFactory} */
+ public final static Logger LOG = LoggerFactory.getLogger(CipherFactory.class);
+
+ /**
+ * Gets a cipher instance for specified algorithm/mode/padding.
+ *
+ * @param props
+ * the configuration properties
+ * @param transformation
+ * algorithm/mode/padding
+ * @return Cipher the cipher. Null value will be returned if no
+ * cipher classes with transformation configured.
+ */
+ public static Cipher getInstance(CipherTransformation transformation,
+ Properties props) throws GeneralSecurityException {
+ List<Class<? extends Cipher>> klasses = getCipherClasses(props);
+ Cipher cipher = null;
+ if (klasses != null) {
+ for (Class<? extends Cipher> klass : klasses) {
+ try {
+ cipher = ReflectionUtils.newInstance(klass, props, transformation);
+ if (cipher != null) {
+ LOG.debug("Using cipher {} for transformation {}.", klass.getName(),
+ transformation.getName());
+ break;
+ }
+ } catch (Exception e) {
+ LOG.error("Cipher {} is not available or transformation {} is not " +
+ "supported.", klass.getName(), transformation.getName());
+ }
+ }
+ }
+
+ return (cipher == null) ? new JceCipher(props, transformation) : cipher;
+ }
+
+ /**
+ * Gets a cipher for algorithm/mode/padding in config value
+ * chimera.crypto.cipher.transformation
+ *
+ * @return Cipher the cipher object Null value will be returned if no
+ * cipher classes with transformation configured.
+ */
+ public static Cipher getInstance(CipherTransformation transformation)
+ throws GeneralSecurityException {
+ return getInstance(transformation, null);
+ }
+
+ private static List<Class<? extends Cipher>> getCipherClasses(Properties props) {
+ List<Class<? extends Cipher>> result = new ArrayList<Class<? extends
+ Cipher>>();
+ String cipherClassString = Utils.getCipherClassString(props);
+ if (cipherClassString == null) {
+ LOG.debug("No cipher classes configured.");
+ return null;
+ }
+ for (String c : Utils.splitClassNames(cipherClassString, ",")) {
+ try {
+ Class<?> cls = ReflectionUtils.getClassByName(c);
+ result.add(cls.asSubclass(Cipher.class));
+ } catch (ClassCastException e) {
+ LOG.error("Class {} is not a Cipher.", c);
+ } catch (ClassNotFoundException e) {
+ LOG.error("Cipher {} not found.", c);
+ }
+ }
+
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/CipherTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/CipherTransformation.java b/src/main/java/org/apache/commons/crypto/cipher/CipherTransformation.java
new file mode 100644
index 0000000..4bf0883
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/CipherTransformation.java
@@ -0,0 +1,96 @@
+/**
+ * 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;
+
+/**
+ * Defines properties of a CipherTransformation. Modeled after the ciphers in
+ * {@link javax.crypto.Cipher}.
+ */
+public enum CipherTransformation {
+
+ /** A crypto transformation representing AES/CTR/NoPadding */
+ AES_CTR_NOPADDING("AES/CTR/NoPadding", 16),
+ /** A crypto transformation representing AES/CBC/NoPadding */
+ AES_CBC_NOPADDING("AES/CBC/NoPadding", 16),
+ /** A crypto transformation representing AES/CBC/PKCS5Padding */
+ AES_CBC_PKCS5PADDING("AES/CBC/PKCS5Padding", 16);
+
+ private final String name;
+ private final int algorithmBlockSize;
+
+ /**
+ * Constructor for CipherTransformation. Initalizes the cipher with algorithm
+ * name and block size of the algorithm.
+ *
+ * @param name the name of cipher algorithm
+ * @param algorithmBlockSize the blockSize of cipher algorithm
+ */
+ CipherTransformation(String name, int algorithmBlockSize) {
+ this.name = name;
+ this.algorithmBlockSize = algorithmBlockSize;
+ }
+
+ /**
+ * Gets the algorithm name of cipher.
+ *
+ * @return name of cipher transformation, as in {@link javax.crypto.Cipher}
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the algorithm block size of cipher.
+ *
+ * @return size of an algorithm block in bytes.
+ */
+ public int getAlgorithmBlockSize() {
+ return algorithmBlockSize;
+ }
+
+ /**
+ * Overrides {@link java.lang.Enum#toString()}
+ *
+ * @return the name of cipher algorithm and blocksize.
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder("{");
+ builder.append("name: " + name);
+ builder.append(", algorithmBlockSize: " + algorithmBlockSize);
+ builder.append("}");
+ return builder.toString();
+ }
+
+ /**
+ * Converts to CipherTransformation from name, {@link #algorithmBlockSize}
+ * is fixed for certain cipher transformation, just need to compare the name.
+ *
+ * @param name cipher transformation name
+ * @return CipherTransformation cipher transformation
+ */
+ public static CipherTransformation fromName(String name) {
+ CipherTransformation[] transformations = CipherTransformation.values();
+ for (CipherTransformation transformation : transformations) {
+ if (transformation.getName().equals(name)) {
+ return transformation;
+ }
+ }
+ throw new IllegalArgumentException("Invalid transformation name: " + name);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/JceCipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/JceCipher.java b/src/main/java/org/apache/commons/crypto/cipher/JceCipher.java
new file mode 100644
index 0000000..99a70bd
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/JceCipher.java
@@ -0,0 +1,207 @@
+/**
+ * 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;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * Implements the {@link org.apache.commons.crypto.cipher.Cipher} using JCE provider.
+ */
+public class JceCipher implements Cipher {
+ private final Properties props;
+ private final CipherTransformation transformation;
+ private final javax.crypto.Cipher cipher;
+
+ /**
+ * Constructs a {@link org.apache.commons.crypto.cipher.Cipher} based on JCE
+ * Cipher {@link javax.crypto.Cipher}.
+ * @param props properties for JCE cipher
+ * @param transformation transformation for JCE cipher
+ * @throws GeneralSecurityException if JCE cipher initialize failed
+ */
+ public JceCipher(Properties props, CipherTransformation transformation)
+ throws GeneralSecurityException {
+ this.props = props;
+ this.transformation = transformation;
+
+ String provider = Utils.getJCEProvider(props);
+ if (provider == null || provider.isEmpty()) {
+ cipher = javax.crypto.Cipher.getInstance(transformation.getName());
+ } else {
+ cipher = javax.crypto.Cipher.getInstance(transformation.getName(), provider);
+ }
+ }
+
+ /**
+ * Gets the CipherTransformation for the jce cipher.
+ *
+ * @return the CipherTransformation for this cipher
+ */
+ @Override
+ public CipherTransformation getTransformation() {
+ return transformation;
+ }
+
+ /**
+ * Gets the properties for the jce cipher.
+ *
+ * @return the properties for this cipher.
+ */
+ @Override
+ public Properties getProperties() {
+ return props;
+ }
+
+ /**
+ * Initializes the cipher with mode, key and iv.
+ *
+ * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
+ * @param key crypto key for the cipher
+ * @param iv Initialization vector for the cipher
+ * @throws InvalidAlgorithmParameterException if the given algorithm
+ * parameters are inappropriate for this cipher, or this cipher requires
+ * algorithm parameters and <code>params</code> is null, or the given
+ * algorithm parameters imply a cryptographic strength that would exceed
+ * the legal limits (as determined from the configured jurisdiction
+ * policy files).
+ */
+ @Override
+ public void init(int mode, byte[] key, byte[] iv)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ Utils.checkNotNull(key);
+ Utils.checkNotNull(iv);
+
+ int cipherMode = javax.crypto.Cipher.DECRYPT_MODE;
+ if (mode == ENCRYPT_MODE)
+ cipherMode = javax.crypto.Cipher.ENCRYPT_MODE;
+
+ cipher.init(cipherMode, new SecretKeySpec(key, "AES"),
+ new IvParameterSpec(iv));
+ }
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data
+ * is encrypted or decrypted, depending on how this cipher was initialized.
+ *
+ * @param inBuffer the input ByteBuffer
+ * @param outBuffer the output ByteBuffer
+ * @return int number of bytes stored in <code>output</code>
+ * @throws ShortBufferException if there is insufficient space
+ * in the output buffer
+ */
+ @Override
+ public int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
+ throws ShortBufferException {
+ return cipher.update(inBuffer, outBuffer);
+ }
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data
+ * is encrypted or decrypted, depending on how this cipher was initialized.
+ *
+ * @param input the input byte array
+ * @param inputOffset the offset in input where the input starts
+ * @param inputLen the input length
+ * @param output the byte array for the result
+ * @param outputOffset the offset in output where the result is stored
+ * @return the number of bytes stored in output
+ * @throws ShortBufferException if there is insufficient space in the output byte array
+ */
+ @Override
+ public int update(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException {
+ return cipher.update(input, inputOffset, inputLen,
+ output, outputOffset);
+ }
+
+ /**
+ * Encrypts or decrypts data in a single-part operation, or finishes a
+ * multiple-part operation. The data is encrypted or decrypted, depending
+ * on how this cipher was initialized.
+ *
+ * @param inBuffer the input ByteBuffer
+ * @param outBuffer the output ByteBuffer
+ * @return int number of bytes stored in <code>output</code>
+ * @throws BadPaddingException if this cipher is in decryption mode,
+ * and (un)padding has been requested, but the decrypted data is not
+ * bounded by the appropriate padding bytes
+ * @throws IllegalBlockSizeException if this cipher is a block cipher,
+ * no padding has been requested (only in encryption mode), and the total
+ * input length of the data processed by this cipher is not a multiple of
+ * block size; or if this encryption algorithm is unable to
+ * process the input data provided.
+ * @throws ShortBufferException if the given output buffer is too small
+ * to hold the result
+ */
+ @Override
+ public int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ return cipher.doFinal(inBuffer, outBuffer);
+ }
+
+ /**
+ * Encrypts or decrypts data in a single-part operation, or finishes a
+ * multiple-part operation.
+ *
+ * @param input the input byte array
+ * @param inputOffset the offset in input where the input starts
+ * @param inputLen the input length
+ * @param output the byte array for the result
+ * @param outputOffset the offset in output where the result is stored
+ * @return the number of bytes stored in output
+ * @throws ShortBufferException if the given output byte array is too small
+ * to hold the result
+ * @throws BadPaddingException if this cipher is in decryption mode,
+ * and (un)padding has been requested, but the decrypted data is not
+ * bounded by the appropriate padding bytes
+ * @throws IllegalBlockSizeException if this cipher is a block cipher,
+ * no padding has been requested (only in encryption mode), and the total
+ * input length of the data processed by this cipher is not a multiple of
+ * block size; or if this encryption algorithm is unable to
+ * process the input data provided.
+ */
+ @Override
+ public int doFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+ return cipher.doFinal(input, inputOffset, inputLen,
+ output, outputOffset);
+ }
+
+ /**
+ * Closes Jce cipher.
+ */
+ @Override
+ public void close() {
+ // Do nothing
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/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
new file mode 100644
index 0000000..9365859
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/Openssl.java
@@ -0,0 +1,320 @@
+/**
+ * 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;
+import java.security.NoSuchAlgorithmException;
+import java.util.StringTokenizer;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.commons.crypto.utils.NativeCodeLoader;
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * OpenSSL cryptographic wrapper using JNI.
+ * Currently only AES-CTR is supported. It's flexible to add
+ * other crypto algorithms/modes.
+ */
+public final class Openssl {
+ private static final Log LOG = LogFactory.getLog(Openssl.class.getName());
+
+ // Mode constant defined by Openssl JNI
+ public static final int ENCRYPT_MODE = 1;
+ public static final int DECRYPT_MODE = 0;
+
+ /** Currently only support AES/CTR/NoPadding. */
+ private static enum AlgorithmMode {
+ AES_CTR,
+ AES_CBC;
+
+ static int get(String algorithm, String mode)
+ throws NoSuchAlgorithmException {
+ try {
+ return AlgorithmMode.valueOf(algorithm + "_" + mode).ordinal();
+ } catch (Exception e) {
+ throw new NoSuchAlgorithmException("Doesn't support algorithm: " +
+ algorithm + " and mode: " + mode);
+ }
+ }
+ }
+
+ private static enum Padding {
+ NoPadding,
+ PKCS5Padding;
+
+ static int get(String padding) throws NoSuchPaddingException {
+ try {
+ return Padding.valueOf(padding).ordinal();
+ } catch (Exception e) {
+ throw new NoSuchPaddingException("Doesn't support padding: " + padding);
+ }
+ }
+ }
+
+ private long context = 0;
+ private final int algorithm;
+ private final int padding;
+
+ private static final String loadingFailureReason;
+
+ static {
+ String loadingFailure = null;
+ try {
+ if (NativeCodeLoader.isNativeCodeLoaded()) {
+ OpensslNative.initIDs();
+ }
+ } catch (Throwable t) {
+ loadingFailure = t.getMessage();
+ LOG.debug("Failed to load OpenSSL Cipher.", t);
+ } finally {
+ loadingFailureReason = loadingFailure;
+ }
+ }
+
+ /**
+ * Gets the failure reason when loading Openssl native.
+ * @return the failure reason.
+ */
+ public static String getLoadingFailureReason() {
+ return loadingFailureReason;
+ }
+
+ private Openssl(long context, int algorithm, int padding) {
+ this.context = context;
+ this.algorithm = algorithm;
+ this.padding = padding;
+ }
+
+ /**
+ * Return an <code>OpensslCipher<code> object that implements the specified
+ * transformation.
+ *
+ * @param transformation the name of the transformation, e.g.,
+ * AES/CTR/NoPadding.
+ * @return OpensslCipher an <code>OpensslCipher<code> object
+ * @throws NoSuchAlgorithmException if <code>transformation</code> is null,
+ * empty, in an invalid format, or if Openssl doesn't implement the
+ * specified algorithm.
+ * @throws NoSuchPaddingException if <code>transformation</code> contains
+ * a padding scheme that is not available.
+ */
+ public static final Openssl getInstance(String transformation)
+ throws NoSuchAlgorithmException, NoSuchPaddingException {
+ Transform transform = tokenizeTransformation(transformation);
+ int algorithmMode = AlgorithmMode.get(transform.algorithm, transform.mode);
+ int padding = Padding.get(transform.padding);
+ long context = OpensslNative.initContext(algorithmMode, padding);
+ return new Openssl(context, algorithmMode, padding);
+ }
+
+ /** Nested class for algorithm, mode and padding. */
+ private static class Transform {
+ final String algorithm;
+ final String mode;
+ final String padding;
+
+ public Transform(String algorithm, String mode, String padding) {
+ this.algorithm = algorithm;
+ this.mode = mode;
+ this.padding = padding;
+ }
+ }
+
+ private static Transform tokenizeTransformation(String transformation)
+ throws NoSuchAlgorithmException {
+ if (transformation == null) {
+ throw new NoSuchAlgorithmException("No transformation given.");
+ }
+
+ /*
+ * Array containing the components of a Cipher transformation:
+ *
+ * index 0: algorithm (e.g., AES)
+ * index 1: mode (e.g., CTR)
+ * index 2: padding (e.g., NoPadding)
+ */
+ String[] parts = new String[3];
+ int count = 0;
+ StringTokenizer parser = new StringTokenizer(transformation, "/");
+ while (parser.hasMoreTokens() && count < 3) {
+ parts[count++] = parser.nextToken().trim();
+ }
+ if (count != 3 || parser.hasMoreTokens()) {
+ throw new NoSuchAlgorithmException("Invalid transformation format: " +
+ transformation);
+ }
+ return new Transform(parts[0], parts[1], parts[2]);
+ }
+
+ /**
+ * Initialize this cipher with a key and IV.
+ *
+ * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
+ * @param key crypto key
+ * @param iv crypto iv
+ */
+ public void init(int mode, byte[] key, byte[] iv) {
+ context = OpensslNative.init(context, mode, algorithm, padding, key, iv);
+ }
+
+ /**
+ * Continues a multiple-part encryption or decryption operation. The data
+ * is encrypted or decrypted, depending on how this cipher was initialized.
+ * <p/>
+ *
+ * All <code>input.remaining()</code> bytes starting at
+ * <code>input.position()</code> are processed. The result is stored in
+ * the output buffer.
+ * <p/>
+ *
+ * Upon return, the input buffer's position will be equal to its limit;
+ * its limit will not have changed. The output buffer's position will have
+ * advanced by n, when n is the value returned by this method; the output
+ * buffer's limit will not have changed.
+ * <p/>
+ *
+ * If <code>output.remaining()</code> bytes are insufficient to hold the
+ * result, a <code>ShortBufferException</code> is thrown.
+ *
+ * @param input the input ByteBuffer
+ * @param output the output ByteBuffer
+ * @return int number of bytes stored in <code>output</code>
+ * @throws ShortBufferException if there is insufficient space in the
+ * output buffer
+ */
+ public int update(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException {
+ checkState();
+ Utils.checkArgument(input.isDirect() && output.isDirect(),
+ "Direct buffers are required.");
+ int len = OpensslNative.update(context, input, input.position(),
+ input.remaining(), output, output.position(), output.remaining());
+ input.position(input.limit());
+ output.position(output.position() + len);
+ return len;
+ }
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data
+ * is encrypted or decrypted, depending on how this cipher was initialized.
+ *
+ * @param input the input byte array
+ * @param inputOffset the offset in input where the input starts
+ * @param inputLen the input length
+ * @param output the byte array for the result
+ * @param outputOffset the offset in output where the result is stored
+ * @return the number of bytes stored in output
+ * @throws ShortBufferException if there is insufficient space in the output byte array
+ */
+ public int update(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException {
+ checkState();
+ return OpensslNative.updateByteArray(context, input, inputOffset, inputLen,
+ output, outputOffset, output.length - outputOffset);
+ }
+
+ /**
+ * Finishes a multiple-part operation. The data is encrypted or decrypted,
+ * depending on how this cipher was initialized.
+ * <p/>
+ *
+ * The result is stored in the output buffer. Upon return, the output buffer's
+ * position will have advanced by n, where n is the value returned by this
+ * method; the output buffer's limit will not have changed.
+ * <p/>
+ *
+ * If <code>output.remaining()</code> bytes are insufficient to hold the result,
+ * a <code>ShortBufferException</code> is thrown.
+ * <p/>
+ *
+ * Upon finishing, this method resets this cipher object to the state it was
+ * in when previously initialized. That is, the object is available to encrypt
+ * or decrypt more data.
+ * <p/>
+ *
+ * If any exception is thrown, this cipher object need to be reset before it
+ * can be used again.
+ *
+ * @param output the output ByteBuffer
+ * @return int number of bytes stored in <code>output</code>
+ * @throws ShortBufferException
+ * @throws IllegalBlockSizeException
+ * @throws BadPaddingException
+ */
+ public int doFinal(ByteBuffer output)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ checkState();
+ Utils.checkArgument(output.isDirect(), "Direct buffer is required.");
+ int len = OpensslNative.doFinal(context, output, output.position(), output.remaining());
+ output.position(output.position() + len);
+ return len;
+ }
+
+ /**
+ * Encrypts or decrypts data in a single-part operation, or finishes a
+ * multiple-part operation.
+ *
+ * @param output the byte array for the result
+ * @param outputOffset the offset in output where the result is stored
+ * @return the number of bytes stored in output
+ * @throws ShortBufferException if the given output byte array is too small
+ * to hold the result
+ * @throws BadPaddingException if this cipher is in decryption mode,
+ * and (un)padding has been requested, but the decrypted data is not
+ * bounded by the appropriate padding bytes
+ * @throws IllegalBlockSizeException if this cipher is a block cipher,
+ * no padding has been requested (only in encryption mode), and the total
+ * input length of the data processed by this cipher is not a multiple of
+ * block size; or if this encryption algorithm is unable to
+ * process the input data provided.
+ */
+ public int doFinal(byte[] output, int outputOffset)
+ throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+ checkState();
+ return OpensslNative.doFinalByteArray(context,
+ output, outputOffset, output.length - outputOffset);
+ }
+
+ /** Forcibly clean the context. */
+ public void clean() {
+ if (context != 0) {
+ OpensslNative.clean(context);
+ context = 0;
+ }
+ }
+
+ /** Checks whether context is initialized. */
+ private void checkState() {
+ Utils.checkState(context != 0);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ clean();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/OpensslCipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpensslCipher.java b/src/main/java/org/apache/commons/crypto/cipher/OpensslCipher.java
new file mode 100644
index 0000000..52b2bf3
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/OpensslCipher.java
@@ -0,0 +1,196 @@
+/**
+ * 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.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * Implements the Cipher using JNI into OpenSSL.
+ */
+public class OpensslCipher implements Cipher {
+ private final Properties props;
+ private final CipherTransformation transformation;
+ private final Openssl cipher;
+
+ /**
+ * Constructs a {@link org.apache.commons.crypto.cipher.Cipher} using JNI into OpenSSL
+ *
+ * @param props properties for OpenSSL cipher
+ * @param transformation transformation for OpenSSL cipher
+ * @throws GeneralSecurityException if OpenSSL cipher initialize failed
+ */
+ public OpensslCipher(Properties props, CipherTransformation transformation)
+ throws GeneralSecurityException {
+ this.props = props;
+ this.transformation = transformation;
+
+ String loadingFailureReason = Openssl.getLoadingFailureReason();
+ if (loadingFailureReason != null) {
+ throw new RuntimeException(loadingFailureReason);
+ }
+
+ cipher = Openssl.getInstance(transformation.getName());
+ }
+
+ /**
+ * Gets the CipherTransformation for the openssl cipher.
+ *
+ * @return the CipherTransformation for this cipher
+ */
+ @Override
+ public CipherTransformation getTransformation() {
+ return transformation;
+ }
+
+ /**
+ * Gets the properties for the openssl cipher.
+ *
+ * @return the properties for this cipher.
+ */
+ @Override
+ public Properties getProperties() {
+ return props;
+ }
+
+ /**
+ * Initializes the cipher with mode, key and iv.
+ * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
+ * @param key crypto key for the cipher
+ * @param iv Initialization vector for the cipher
+ * @throws IOException if cipher initialize fails
+ */
+ @Override
+ public void init(int mode, byte[] key, byte[] iv) {
+ Utils.checkNotNull(key);
+ Utils.checkNotNull(iv);
+
+ int cipherMode = Openssl.DECRYPT_MODE;
+ if (mode == ENCRYPT_MODE)
+ cipherMode = Openssl.ENCRYPT_MODE;
+
+ cipher.init(cipherMode, key, iv);
+ }
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data
+ * is encrypted or decrypted, depending on how this cipher was initialized.
+ * @param inBuffer the input ByteBuffer
+ * @param outBuffer the output ByteBuffer
+ * @return int number of bytes stored in <code>output</code>
+ * @throws ShortBufferException if there is insufficient space
+ * in the output buffer
+ */
+ @Override
+ public int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
+ throws ShortBufferException {
+ return cipher.update(inBuffer, outBuffer);
+ }
+
+ /**
+ * Continues a multiple-part encryption/decryption operation. The data
+ * is encrypted or decrypted, depending on how this cipher was initialized.
+ *
+ * @param input the input byte array
+ * @param inputOffset the offset in input where the input starts
+ * @param inputLen the input length
+ * @param output the byte array for the result
+ * @param outputOffset the offset in output where the result is stored
+ * @return the number of bytes stored in output
+ * @throws ShortBufferException if there is insufficient space in the output byte array
+ */
+ @Override
+ public int update(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException {
+ return cipher.update(input, inputOffset, inputLen,
+ output, outputOffset);
+ }
+
+ /**
+ * Encrypts or decrypts data in a single-part operation, or finishes a
+ * multiple-part operation. The data is encrypted or decrypted, depending
+ * on how this cipher was initialized.
+ * @param inBuffer the input ByteBuffer
+ * @param outBuffer the output ByteBuffer
+ * @return int number of bytes stored in <code>output</code>
+ * @throws BadPaddingException if this cipher is in decryption mode,
+ * and (un)padding has been requested, but the decrypted data is not
+ * bounded by the appropriate padding bytes
+ * @throws IllegalBlockSizeException if this cipher is a block cipher,
+ * no padding has been requested (only in encryption mode), and the total
+ * input length of the data processed by this cipher is not a multiple of
+ * block size; or if this encryption algorithm is unable to
+ * process the input data provided.
+ * @throws ShortBufferException if the given output buffer is too small
+ * to hold the result
+ */
+ @Override
+ public int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ int n = cipher.update(inBuffer, outBuffer);
+ return n + cipher.doFinal(outBuffer);
+ }
+
+ /**
+ * Encrypts or decrypts data in a single-part operation, or finishes a
+ * multiple-part operation.
+ *
+ * @param input the input byte array
+ * @param inputOffset the offset in input where the input starts
+ * @param inputLen the input length
+ * @param output the byte array for the result
+ * @param outputOffset the offset in output where the result is stored
+ * @return the number of bytes stored in output
+ * @throws ShortBufferException if the given output byte array is too small
+ * to hold the result
+ * @throws BadPaddingException if this cipher is in decryption mode,
+ * and (un)padding has been requested, but the decrypted data is not
+ * bounded by the appropriate padding bytes
+ * @throws IllegalBlockSizeException if this cipher is a block cipher,
+ * no padding has been requested (only in encryption mode), and the total
+ * input length of the data processed by this cipher is not a multiple of
+ * block size; or if this encryption algorithm is unable to
+ * process the input data provided.
+ */
+ @Override
+ public int doFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset)
+ throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+ int n = cipher.update(input, inputOffset, inputLen,
+ output, outputOffset);
+ return n + cipher.doFinal(output, outputOffset + n);
+ }
+
+ /**
+ * Closes the OpenSSL cipher. Clean the Openssl native context.
+ */
+ @Override
+ public void close() {
+ cipher.clean();
+ }
+}
[8/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
Posted by xu...@apache.org.
CRYPTO-7: Rename source code in Chimera to Apache name space
Update some typos in README
Project: http://git-wip-us.apache.org/repos/asf/commons-crypto/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-crypto/commit/4920d272
Tree: http://git-wip-us.apache.org/repos/asf/commons-crypto/tree/4920d272
Diff: http://git-wip-us.apache.org/repos/asf/commons-crypto/diff/4920d272
Branch: refs/heads/master
Commit: 4920d2729c0b3eb492c5fd9f890a463996eb2ea9
Parents: 92d129a
Author: Ferdinand Xu <ch...@intel.com>
Authored: Fri Apr 15 08:47:50 2016 +0800
Committer: Ferdinand Xu <ch...@intel.com>
Committed: Fri Apr 22 05:56:25 2016 +0800
----------------------------------------------------------------------
Makefile | 18 +-
Makefile.common | 14 +-
README.md | 20 +-
pom.xml | 6 +-
src/main/java/com/intel/chimera/VERSION | 1 -
.../java/com/intel/chimera/cipher/Cipher.java | 155 ------
.../com/intel/chimera/cipher/CipherFactory.java | 105 -----
.../chimera/cipher/CipherTransformation.java | 96 ----
.../com/intel/chimera/cipher/JceCipher.java | 207 --------
.../java/com/intel/chimera/cipher/Openssl.java | 320 -------------
.../com/intel/chimera/cipher/OpensslCipher.java | 196 --------
.../com/intel/chimera/cipher/OpensslNative.java | 116 -----
.../com/intel/chimera/cipher/package-info.java | 22 -
.../intel/chimera/conf/ConfigurationKeys.java | 139 ------
.../com/intel/chimera/conf/package-info.java | 21 -
.../intel/chimera/random/JavaSecureRandom.java | 73 ---
.../chimera/random/OpensslSecureRandom.java | 140 ------
.../random/OpensslSecureRandomNative.java | 40 --
.../intel/chimera/random/OsSecureRandom.java | 133 ------
.../com/intel/chimera/random/SecureRandom.java | 36 --
.../chimera/random/SecureRandomFactory.java | 72 ---
.../com/intel/chimera/random/package-info.java | 21 -
.../chimera/stream/CTRCryptoInputStream.java | 423 -----------------
.../chimera/stream/CTRCryptoOutputStream.java | 230 ---------
.../intel/chimera/stream/CryptoInputStream.java | 394 ----------------
.../chimera/stream/CryptoOutputStream.java | 283 -----------
.../stream/PositionedCryptoInputStream.java | 311 ------------
.../chimera/stream/input/ChannelInput.java | 165 -------
.../com/intel/chimera/stream/input/Input.java | 133 ------
.../intel/chimera/stream/input/StreamInput.java | 164 -------
.../chimera/stream/output/ChannelOutput.java | 78 ----
.../com/intel/chimera/stream/output/Output.java | 76 ---
.../chimera/stream/output/StreamOutput.java | 101 ----
.../java/com/intel/chimera/utils/IOUtils.java | 96 ----
.../intel/chimera/utils/NativeCodeLoader.java | 279 -----------
.../java/com/intel/chimera/utils/OSInfo.java | 190 --------
.../intel/chimera/utils/ReflectionUtils.java | 204 --------
.../java/com/intel/chimera/utils/Utils.java | 362 --------------
.../com/intel/chimera/utils/package-info.java | 21 -
src/main/java/org/apache/commons/crypto/VERSION | 1 +
.../apache/commons/crypto/cipher/Cipher.java | 155 ++++++
.../commons/crypto/cipher/CipherFactory.java | 105 +++++
.../crypto/cipher/CipherTransformation.java | 96 ++++
.../apache/commons/crypto/cipher/JceCipher.java | 207 ++++++++
.../apache/commons/crypto/cipher/Openssl.java | 320 +++++++++++++
.../commons/crypto/cipher/OpensslCipher.java | 196 ++++++++
.../commons/crypto/cipher/OpensslNative.java | 116 +++++
.../commons/crypto/cipher/package-info.java | 22 +
.../commons/crypto/conf/ConfigurationKeys.java | 139 ++++++
.../commons/crypto/conf/package-info.java | 21 +
.../commons/crypto/random/JavaSecureRandom.java | 73 +++
.../crypto/random/OpensslSecureRandom.java | 140 ++++++
.../random/OpensslSecureRandomNative.java | 40 ++
.../commons/crypto/random/OsSecureRandom.java | 133 ++++++
.../commons/crypto/random/SecureRandom.java | 36 ++
.../crypto/random/SecureRandomFactory.java | 72 +++
.../commons/crypto/random/package-info.java | 21 +
.../crypto/stream/CTRCryptoInputStream.java | 423 +++++++++++++++++
.../crypto/stream/CTRCryptoOutputStream.java | 230 +++++++++
.../crypto/stream/CryptoInputStream.java | 394 ++++++++++++++++
.../crypto/stream/CryptoOutputStream.java | 283 +++++++++++
.../stream/PositionedCryptoInputStream.java | 311 ++++++++++++
.../crypto/stream/input/ChannelInput.java | 165 +++++++
.../commons/crypto/stream/input/Input.java | 133 ++++++
.../crypto/stream/input/StreamInput.java | 164 +++++++
.../crypto/stream/output/ChannelOutput.java | 78 ++++
.../commons/crypto/stream/output/Output.java | 76 +++
.../crypto/stream/output/StreamOutput.java | 101 ++++
.../apache/commons/crypto/utils/IOUtils.java | 96 ++++
.../commons/crypto/utils/NativeCodeLoader.java | 279 +++++++++++
.../org/apache/commons/crypto/utils/OSInfo.java | 190 ++++++++
.../commons/crypto/utils/ReflectionUtils.java | 204 ++++++++
.../org/apache/commons/crypto/utils/Utils.java | 362 ++++++++++++++
.../commons/crypto/utils/package-info.java | 21 +
.../com/intel/chimera/cipher/OpensslNative.c | 467 -------------------
.../com/intel/chimera/com_intel_chimera.h | 228 ---------
src/main/native/com/intel/chimera/exception.c | 124 -----
src/main/native/com/intel/chimera/exception.h | 104 -----
.../chimera/random/OpensslSecureRandomNative.c | 335 -------------
.../chimera/random/com_intel_chimera_random.h | 40 --
.../commons/crypto/cipher/OpensslNative.c | 467 +++++++++++++++++++
.../org/apache/commons/crypto/exception.c | 124 +++++
.../org/apache/commons/crypto/exception.h | 104 +++++
.../commons/crypto/org_apache_commons_crypto.h | 228 +++++++++
.../crypto/random/OpensslSecureRandomNative.c | 335 +++++++++++++
.../random/org_apache_commons_crypto_random.h | 40 ++
.../chimera/cipher/AbstractCipherTest.java | 242 ----------
.../com/intel/chimera/cipher/JceCipherTest.java | 32 --
.../intel/chimera/cipher/OpensslCipherTest.java | 165 -------
.../java/com/intel/chimera/cipher/TestData.java | 160 -------
.../chimera/random/AbstractRandomTest.java | 57 ---
.../chimera/random/TestJavaSecureRandom.java | 40 --
.../chimera/random/TestOpensslSecureRandom.java | 40 --
.../chimera/random/TestOsSecureRandom.java | 29 --
.../stream/AbstractCryptoStreamTest.java | 456 ------------------
.../stream/CBCNoPaddingCryptoStreamTest.java | 31 --
.../stream/CBCPKCS5PaddingCryptoStreamTest.java | 30 --
.../chimera/stream/CTRCryptoStreamTest.java | 58 ---
.../stream/CTRNoPaddingCryptoStreamTest.java | 31 --
.../stream/PositionedCryptoInputStreamTest.java | 381 ---------------
.../java/com/intel/chimera/utils/UtilsTest.java | 40 --
.../crypto/cipher/AbstractCipherTest.java | 242 ++++++++++
.../commons/crypto/cipher/JceCipherTest.java | 32 ++
.../crypto/cipher/OpensslCipherTest.java | 165 +++++++
.../apache/commons/crypto/cipher/TestData.java | 160 +++++++
.../crypto/random/AbstractRandomTest.java | 57 +++
.../crypto/random/TestJavaSecureRandom.java | 40 ++
.../crypto/random/TestOpensslSecureRandom.java | 40 ++
.../crypto/random/TestOsSecureRandom.java | 29 ++
.../crypto/stream/AbstractCryptoStreamTest.java | 456 ++++++++++++++++++
.../stream/CBCNoPaddingCryptoStreamTest.java | 31 ++
.../stream/CBCPKCS5PaddingCryptoStreamTest.java | 30 ++
.../crypto/stream/CTRCryptoStreamTest.java | 58 +++
.../stream/CTRNoPaddingCryptoStreamTest.java | 31 ++
.../stream/PositionedCryptoInputStreamTest.java | 381 +++++++++++++++
.../apache/commons/crypto/utils/UtilsTest.java | 40 ++
116 files changed, 8522 insertions(+), 8522 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/Makefile
----------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index e0a605e..8309b5c 100644
--- a/Makefile
+++ b/Makefile
@@ -11,30 +11,30 @@ else
TAR:= tar
endif
-NATIVE_TARGET_DIR:=$(TARGET)/classes/com/intel/chimera/native/$(OS_NAME)/$(OS_ARCH)
+NATIVE_TARGET_DIR:=$(TARGET)/classes/org/apache/commons/crypto/native/$(OS_NAME)/$(OS_ARCH)
NATIVE_DLL:=$(NATIVE_TARGET_DIR)/$(LIBNAME)
all: $(NATIVE_DLL)
-$(TARGET)/jni-classes/com/intel/chimera/cipher/OpensslNative.class : $(SRC)/com/intel/chimera/cipher/OpensslNative.java
+$(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpensslNative.class : $(SRC)/org/apache/commons/crypto/cipher/OpensslNative.java
@mkdir -p $(TARGET)/jni-classes
$(JAVAC) -source 1.6 -target 1.6 -d $(TARGET)/jni-classes -sourcepath $(SRC) $<
-$(TARGET)/jni-classes/com/intel/chimera/random/OpensslSecureRandomNative.class : $(SRC)/com/intel/chimera/random/OpensslSecureRandomNative.java
+$(TARGET)/jni-classes/org/apache/commons/crypto/random/OpensslSecureRandomNative.class : $(SRC)/org/apache/commons/crypto/random/OpensslSecureRandomNative.java
@mkdir -p $(TARGET)/jni-classes
$(JAVAC) -source 1.6 -target 1.6 -d $(TARGET)/jni-classes -sourcepath $(SRC) $<
-$(TARGET)/jni-classes/com/intel/chimera/cipher/OpensslNative.h: $(TARGET)/jni-classes/com/intel/chimera/cipher/OpensslNative.class
- $(JAVAH) -force -classpath $(TARGET)/jni-classes -o $@ com.intel.chimera.cipher.OpensslNative
+$(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpensslNative.h: $(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpensslNative.class
+ $(JAVAH) -force -classpath $(TARGET)/jni-classes -o $@ org.apache.commons.crypto.cipher.OpensslNative
-$(TARGET)/jni-classes/com/intel/chimera/random/OpensslSecureRandomNative.h: $(TARGET)/jni-classes/com/intel/chimera/random/OpensslSecureRandomNative.class
- $(JAVAH) -force -classpath $(TARGET)/jni-classes -o $@ com.intel.chimera.random.OpensslSecureRandomNative
+$(TARGET)/jni-classes/org/apache/commons/crypto/random/OpensslSecureRandomNative.h: $(TARGET)/jni-classes/org/apache/commons/crypto/random/OpensslSecureRandomNative.class
+ $(JAVAH) -force -classpath $(TARGET)/jni-classes -o $@ org.apache.commons.crypto.random.OpensslSecureRandomNative
-$(CHIMERA_OUT)/OpensslNative.o : $(SRC_NATIVE)/com/intel/chimera/cipher/OpensslNative.c $(TARGET)/jni-classes/com/intel/chimera/cipher/OpensslNative.h
+$(CHIMERA_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 $@
-$(CHIMERA_OUT)/OpensslSecureRandom.o : $(SRC_NATIVE)/com/intel/chimera/random/OpensslSecureRandomNative.c $(TARGET)/jni-classes/com/intel/chimera/random/OpensslSecureRandomNative.h
+$(CHIMERA_OUT)/OpensslSecureRandom.o : $(SRC_NATIVE)/org/apache/commons/crypto/random/OpensslSecureRandomNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/random/OpensslSecureRandomNative.h
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $< -o $@
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/Makefile.common
----------------------------------------------------------------------
diff --git a/Makefile.common b/Makefile.common
index 2a45bdd..8091727 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1,7 +1,7 @@
TARGET:=target
SRC:=src/main/java
SRC_NATIVE:=src/main/native
-include $(SRC)/com/intel/chimera/VERSION
+include $(SRC)/org/apache/commons/crypto/VERSION
ifndef JAVA_HOME
$(error Set JAVA_HOME environment variable)
@@ -12,13 +12,13 @@ JAVA := "$$JAVA_HOME/bin/java"
JAVAC := "$$JAVA_HOME/bin/javac"
JAVAH := "$$JAVA_HOME/bin/javah"
-OSINFO_CLASS := com.intel.chimera.utils.OSInfo
-OSINFO_PROG := lib/com/intel/chimera/utils/OSInfo.class
+OSINFO_CLASS := org.apache.commons.crypto.utils.OSInfo
+OSINFO_PROG := lib/org/apache/commons/crypto/utils/OSInfo.class
## building OSInfo.java
$(info compiling OSInfo.java)
$(shell mkdir -p lib)
-$(shell $(JAVAC) src/main/java/com/intel/chimera/utils/OSInfo.java -d lib)
+$(shell $(JAVAC) src/main/java/org/apache/commons/crypto/utils/OSInfo.java -d lib)
OS_NAME := $(shell $(JAVA) -cp lib $(OSINFO_CLASS) --os)
OS_ARCH := $(shell $(JAVA) -cp lib $(OSINFO_CLASS) --arch)
@@ -252,9 +252,9 @@ LIBNAME := $($(os_arch)_LIBNAME)
CHIMERA_FLAGS := $($(os_arch)_CHIMERA_FLAGS)
-CFLAGS := $(CFLAGS) -Ilib/include -I/usr/include -I"$(SRC_NATIVE)/com/intel/chimera/"
+CFLAGS := $(CFLAGS) -Ilib/include -I/usr/include -I"$(SRC_NATIVE)/org/apache/commons/crypto/"
CXXFLAGS := $(CXXFLAGS) -Ilib/include -I/usr/include
ifneq ($(jni_include),)
-CFLAGS := $(CFLAGS) -I"$(jni_include)" -I"$(TARGET)/jni-classes/com/intel/chimera/cipher" -I"$(TARGET)/jni-classes/com/intel/chimera/random"
-CXXFLAGS := $(CXXFLAGS) -I"$(jni_include)" -I"$(TARGET)/jni-classes/com/intel/chimera/cipher" -I"$(TARGET)/jni-classes/com/intel/chimera/random"
+CFLAGS := $(CFLAGS) -I"$(jni_include)" -I"$(TARGET)/jni-classes/org/apache/commons/crypto/cipher" -I"$(TARGET)/jni-classes/org/apache/commons/crypto/random"
+CXXFLAGS := $(CXXFLAGS) -I"$(jni_include)" -I"$(TARGET)/jni-classes/org/apache/commons/crypto/cipher" -I"$(TARGET)/jni-classes/org/apache/commons/crypto/random"
endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index e87f014..34845c0 100644
--- a/README.md
+++ b/README.md
@@ -10,17 +10,17 @@ Chimera [. Free for both commercial and non-commercial use.
## Download
- * Release version: http://central.maven.org/maven2/com/intel/chimera/chimera/
- * Snapshot version (the latest beta version): https://oss.sonatype.org/content/repositories/snapshots/com/intel/chimera/chimera/
+ * Release version: http://central.maven.org/maven2/org/apache/commons/crypto/chimera/
+ * Snapshot version (the latest beta version): https://oss.sonatype.org/content/repositories/snapshots/org/apache/commons/crypto/chimera/
### Using with Maven
- * Chimera is available from Maven's central repository: <http://central.maven.org/maven2/com/intel/chimera/chimera>
+ * Chimera is available from Maven's central repository: <http://central.maven.org/maven2/org/apache/commons/crypto/chimera>
Add the following dependency to your pom.xml:
<dependency>
- <groupId>com.intel.chimera</groupId>
- <artifactId>chimera</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-crypto</artifactId>
<version>0.9.0</version>
<type>jar</type>
<scope>compile</scope>
@@ -29,7 +29,7 @@ Add the following dependency to your pom.xml:
### Using with sbt
```
-libraryDependencies += "com.intel.chimera" % "chimera" % "0.9.0"
+libraryDependencies += "org.apache.commons" % "commons-crypto" % "0.9.0"
```
## Usage
@@ -37,7 +37,7 @@ libraryDependencies += "com.intel.chimera" % "chimera" % "0.9.0"
```java
Properties properties = new Properties();
-properties.setProperty("chimera.crypto.cipher.classes", "com.intel.chimera.crypto.OpensslCipher");
+properties.setProperty("chimera.crypto.cipher.classes", "org.apache.commons.crypto.cipher.OpensslCipher");
Cipher cipher = Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, properties);
byte[] key = new byte[16];
@@ -61,15 +61,15 @@ int decryptedLen = cis.read(decryptedData, 0, 1024);
### Configuration
Currently, two ciphers are supported: JceCipher and OpensslCipher, you can configure which cipher to use as follows:
- $ java -Dchimera.crypto.cipher.classes=com.intel.chimera.crypto.OpensslCipher Sample
- $ java -Dchimera.crypto.cipher.classes=com.intel.chimera.crypto.JceCipher Sample
+ $ java -Dchimera.crypto.cipher.classes=org.apache.commons.crypto.cipher.OpensslCipher Sample
+ $ java -Dchimera.crypto.cipher.classes=org.apache.commons.crypto.cipher.JceCipher Sample
More detailed information about the configurations are as follows.
| Property Name | Default | Meaning |
| --------------|---------|-------------------------|
| chimera.crypto.cipher.transformation | AES/CTR/NoPadding | The value is identical to the transformations described in the Cipher section of the Java Cryptography Architecture Standard Algorithm Name Documentation. Currently only "AES/CTR/NoPadding" algorithm is supported.|
-| chimera.crypto.cipher.classes | com.intel.chimera.crypto.OpensslCipher, com.intel.chimera.crypto.JceCipher | Comma-separated list of cipher classes which implement cipher algorithm of "AES/CTR/NoPadding". A cipher implementation encapsulates the encryption and decryption details. The first available implementation appearing in this list will be used. |
+| chimera.crypto.cipher.classes | org.apache.commons.crypto.cipher.OpensslCipher, org.apache.commons.crypto.cipher.JceCipher | Comma-separated list of cipher classes which implement cipher algorithm of "AES/CTR/NoPadding". A cipher implementation encapsulates the encryption and decryption details. The first available implementation appearing in this list will be used. |
## Building from the source code
Building from the source code is an option when your OS platform and CPU architecture is not supported. To build Chimera, you need JDK 1.7 or higher, OpenSSL 1.0.1c or higher, etc.
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 90c902a..03f52e4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,8 +17,8 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>com.intel.chimera</groupId>
- <artifactId>chimera</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-crypto</artifactId>
<packaging>jar</packaging>
<description>chimera: A fast encryption/decryption library</description>
<version>1.0.0-SNAPSHOT</version>
@@ -323,7 +323,7 @@
<exclude>Makefile.common</exclude>
<exclude>project/project/target/config-classes/*</exclude>
<exclude>project/target/</exclude>
- <exclude>src/main/java/com/intel/chimera/VERSION</exclude>
+ <exclude>src/main/java/org/apache/commons/crypto/VERSION</exclude>
</excludes>
</configuration>
</plugin>
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/VERSION
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/VERSION b/src/main/java/com/intel/chimera/VERSION
deleted file mode 100644
index baca170..0000000
--- a/src/main/java/com/intel/chimera/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-VERSION=1.0.0-SNAPSHOT
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/cipher/Cipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/cipher/Cipher.java b/src/main/java/com/intel/chimera/cipher/Cipher.java
deleted file mode 100644
index ff1b118..0000000
--- a/src/main/java/com/intel/chimera/cipher/Cipher.java
+++ /dev/null
@@ -1,155 +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 com.intel.chimera.cipher;
-
-import java.io.Closeable;
-import java.nio.ByteBuffer;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-
-/**
- * The interface of cryptographic cipher for encryption and decryption.
- */
-public interface Cipher extends Closeable {
-
- /**
- * A constant representing encrypt mode. The mode constant to be used
- * when calling init method of the Cipher.
- */
- int ENCRYPT_MODE = 1;
-
- /**
- * A constant representing decrypt mode. The mode constant to be used
- * when calling init method of the Cipher.
- */
- int DECRYPT_MODE = 0;
-
- /**
- * Gets the CipherTransformation for this cipher.
- *
- * @return the CipherTransformation for this cipher.
- */
- CipherTransformation getTransformation();
-
- /**
- * Gets the properties for this cipher.
- *
- * @return the properties for this cipher.
- */
- Properties getProperties();
-
- /**
- * Initializes the cipher with mode, key and iv.
- *
- * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
- * @param key crypto key for the cipher
- * @param iv Initialization vector for the cipher
- * @throws InvalidKeyException if the given key is inappropriate for
- * initializing this cipher, or its keysize exceeds the maximum allowable
- * keysize (as determined from the configured jurisdiction policy files).
- * @throws InvalidAlgorithmParameterException if the given algorithm
- * parameters are inappropriate for this cipher, or this cipher requires
- * algorithm parameters and <code>params</code> is null, or the given
- * algorithm parameters imply a cryptographic strength that would exceed
- * the legal limits (as determined from the configured jurisdiction
- * policy files).
- */
- void init(int mode, byte[] key, byte[] iv)
- throws InvalidKeyException, InvalidAlgorithmParameterException;
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data
- * is encrypted or decrypted, depending on how this cipher was initialized.
- *
- * @param inBuffer the input ByteBuffer
- * @param outBuffer the output ByteBuffer
- * @return int number of bytes stored in <code>output</code>
- * @throws ShortBufferException if there is insufficient space
- * in the output buffer
- */
- int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
- throws ShortBufferException;
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data
- * is encrypted or decrypted, depending on how this cipher was initialized.
- *
- * @param input the input byte array
- * @param inputOffset the offset in input where the input starts
- * @param inputLen the input length
- * @param output the byte array for the result
- * @param outputOffset the offset in output where the result is stored
- * @return the number of bytes stored in output
- * @throws ShortBufferException if there is insufficient space in the output byte array
- */
- int update(byte[] input, int inputOffset, int inputLen,
- byte[] output, int outputOffset)
- throws ShortBufferException;
-
- /**
- * Encrypts or decrypts data in a single-part operation, or finishes a
- * multiple-part operation.
- *
- * @param inBuffer the input ByteBuffer
- * @param outBuffer the output ByteBuffer
- * @return int number of bytes stored in <code>output</code>
- * @throws BadPaddingException if this cipher is in decryption mode,
- * and (un)padding has been requested, but the decrypted data is not
- * bounded by the appropriate padding bytes
- * @throws IllegalBlockSizeException if this cipher is a block cipher,
- * no padding has been requested (only in encryption mode), and the total
- * input length of the data processed by this cipher is not a multiple of
- * block size; or if this encryption algorithm is unable to
- * process the input data provided.
- * @throws ShortBufferException if the given output buffer is too small
- * to hold the result
- */
- int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
- throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException;
-
- /**
- * Encrypts or decrypts data in a single-part operation, or finishes a
- * multiple-part operation.
- *
- * @param input the input byte array
- * @param inputOffset the offset in input where the input starts
- * @param inputLen the input length
- * @param output the byte array for the result
- * @param outputOffset the offset in output where the result is stored
- * @return the number of bytes stored in output
- * @throws ShortBufferException if the given output byte array is too small
- * to hold the result
- * @throws BadPaddingException if this cipher is in decryption mode,
- * and (un)padding has been requested, but the decrypted data is not
- * bounded by the appropriate padding bytes
- * @throws IllegalBlockSizeException if this cipher is a block cipher,
- * no padding has been requested (only in encryption mode), and the total
- * input length of the data processed by this cipher is not a multiple of
- * block size; or if this encryption algorithm is unable to
- * process the input data provided.
- */
- int doFinal(byte[] input, int inputOffset, int inputLen,
- byte[] output, int outputOffset)
- throws ShortBufferException, IllegalBlockSizeException, BadPaddingException;
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/cipher/CipherFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/cipher/CipherFactory.java b/src/main/java/com/intel/chimera/cipher/CipherFactory.java
deleted file mode 100644
index f612830..0000000
--- a/src/main/java/com/intel/chimera/cipher/CipherFactory.java
+++ /dev/null
@@ -1,105 +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 com.intel.chimera.cipher;
-
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import com.intel.chimera.utils.ReflectionUtils;
-import com.intel.chimera.utils.Utils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is the factory class used for creating cipher class
- */
-public class CipherFactory {
-
- /** LOG instance for {@CipherFactory} */
- public final static Logger LOG = LoggerFactory.getLogger(CipherFactory.class);
-
- /**
- * Gets a cipher instance for specified algorithm/mode/padding.
- *
- * @param props
- * the configuration properties
- * @param transformation
- * algorithm/mode/padding
- * @return Cipher the cipher. Null value will be returned if no
- * cipher classes with transformation configured.
- */
- public static Cipher getInstance(CipherTransformation transformation,
- Properties props) throws GeneralSecurityException {
- List<Class<? extends Cipher>> klasses = getCipherClasses(props);
- Cipher cipher = null;
- if (klasses != null) {
- for (Class<? extends Cipher> klass : klasses) {
- try {
- cipher = ReflectionUtils.newInstance(klass, props, transformation);
- if (cipher != null) {
- LOG.debug("Using cipher {} for transformation {}.", klass.getName(),
- transformation.getName());
- break;
- }
- } catch (Exception e) {
- LOG.error("Cipher {} is not available or transformation {} is not " +
- "supported.", klass.getName(), transformation.getName());
- }
- }
- }
-
- return (cipher == null) ? new JceCipher(props, transformation) : cipher;
- }
-
- /**
- * Gets a cipher for algorithm/mode/padding in config value
- * chimera.crypto.cipher.transformation
- *
- * @return Cipher the cipher object Null value will be returned if no
- * cipher classes with transformation configured.
- */
- public static Cipher getInstance(CipherTransformation transformation)
- throws GeneralSecurityException {
- return getInstance(transformation, null);
- }
-
- private static List<Class<? extends Cipher>> getCipherClasses(Properties props) {
- List<Class<? extends Cipher>> result = new ArrayList<Class<? extends
- Cipher>>();
- String cipherClassString = Utils.getCipherClassString(props);
- if (cipherClassString == null) {
- LOG.debug("No cipher classes configured.");
- return null;
- }
- for (String c : Utils.splitClassNames(cipherClassString, ",")) {
- try {
- Class<?> cls = ReflectionUtils.getClassByName(c);
- result.add(cls.asSubclass(Cipher.class));
- } catch (ClassCastException e) {
- LOG.error("Class {} is not a Cipher.", c);
- } catch (ClassNotFoundException e) {
- LOG.error("Cipher {} not found.", c);
- }
- }
-
- return result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/cipher/CipherTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/cipher/CipherTransformation.java b/src/main/java/com/intel/chimera/cipher/CipherTransformation.java
deleted file mode 100644
index 3714bbb..0000000
--- a/src/main/java/com/intel/chimera/cipher/CipherTransformation.java
+++ /dev/null
@@ -1,96 +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 com.intel.chimera.cipher;
-
-/**
- * Defines properties of a CipherTransformation. Modeled after the ciphers in
- * {@link javax.crypto.Cipher}.
- */
-public enum CipherTransformation {
-
- /** A crypto transformation representing AES/CTR/NoPadding */
- AES_CTR_NOPADDING("AES/CTR/NoPadding", 16),
- /** A crypto transformation representing AES/CBC/NoPadding */
- AES_CBC_NOPADDING("AES/CBC/NoPadding", 16),
- /** A crypto transformation representing AES/CBC/PKCS5Padding */
- AES_CBC_PKCS5PADDING("AES/CBC/PKCS5Padding", 16);
-
- private final String name;
- private final int algorithmBlockSize;
-
- /**
- * Constructor for CipherTransformation. Initalizes the cipher with algorithm
- * name and block size of the algorithm.
- *
- * @param name the name of cipher algorithm
- * @param algorithmBlockSize the blockSize of cipher algorithm
- */
- CipherTransformation(String name, int algorithmBlockSize) {
- this.name = name;
- this.algorithmBlockSize = algorithmBlockSize;
- }
-
- /**
- * Gets the algorithm name of cipher.
- *
- * @return name of cipher transformation, as in {@link javax.crypto.Cipher}
- */
- public String getName() {
- return name;
- }
-
- /**
- * Gets the algorithm block size of cipher.
- *
- * @return size of an algorithm block in bytes.
- */
- public int getAlgorithmBlockSize() {
- return algorithmBlockSize;
- }
-
- /**
- * Overrides {@link java.lang.Enum#toString()}
- *
- * @return the name of cipher algorithm and blocksize.
- */
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder("{");
- builder.append("name: " + name);
- builder.append(", algorithmBlockSize: " + algorithmBlockSize);
- builder.append("}");
- return builder.toString();
- }
-
- /**
- * Converts to CipherTransformation from name, {@link #algorithmBlockSize}
- * is fixed for certain cipher transformation, just need to compare the name.
- *
- * @param name cipher transformation name
- * @return CipherTransformation cipher transformation
- */
- public static CipherTransformation fromName(String name) {
- CipherTransformation[] transformations = CipherTransformation.values();
- for (CipherTransformation transformation : transformations) {
- if (transformation.getName().equals(name)) {
- return transformation;
- }
- }
- throw new IllegalArgumentException("Invalid transformation name: " + name);
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/cipher/JceCipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/cipher/JceCipher.java b/src/main/java/com/intel/chimera/cipher/JceCipher.java
deleted file mode 100644
index a46ecd8..0000000
--- a/src/main/java/com/intel/chimera/cipher/JceCipher.java
+++ /dev/null
@@ -1,207 +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 com.intel.chimera.cipher;
-
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-import com.intel.chimera.utils.Utils;
-
-/**
- * Implements the {@link com.intel.chimera.cipher.Cipher} using JCE provider.
- */
-public class JceCipher implements Cipher {
- private final Properties props;
- private final CipherTransformation transformation;
- private final javax.crypto.Cipher cipher;
-
- /**
- * Constructs a {@link com.intel.chimera.cipher.Cipher} based on JCE
- * Cipher {@link javax.crypto.Cipher}.
- * @param props properties for JCE cipher
- * @param transformation transformation for JCE cipher
- * @throws GeneralSecurityException if JCE cipher initialize failed
- */
- public JceCipher(Properties props, CipherTransformation transformation)
- throws GeneralSecurityException {
- this.props = props;
- this.transformation = transformation;
-
- String provider = Utils.getJCEProvider(props);
- if (provider == null || provider.isEmpty()) {
- cipher = javax.crypto.Cipher.getInstance(transformation.getName());
- } else {
- cipher = javax.crypto.Cipher.getInstance(transformation.getName(), provider);
- }
- }
-
- /**
- * Gets the CipherTransformation for the jce cipher.
- *
- * @return the CipherTransformation for this cipher
- */
- @Override
- public CipherTransformation getTransformation() {
- return transformation;
- }
-
- /**
- * Gets the properties for the jce cipher.
- *
- * @return the properties for this cipher.
- */
- @Override
- public Properties getProperties() {
- return props;
- }
-
- /**
- * Initializes the cipher with mode, key and iv.
- *
- * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
- * @param key crypto key for the cipher
- * @param iv Initialization vector for the cipher
- * @throws InvalidAlgorithmParameterException if the given algorithm
- * parameters are inappropriate for this cipher, or this cipher requires
- * algorithm parameters and <code>params</code> is null, or the given
- * algorithm parameters imply a cryptographic strength that would exceed
- * the legal limits (as determined from the configured jurisdiction
- * policy files).
- */
- @Override
- public void init(int mode, byte[] key, byte[] iv)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- Utils.checkNotNull(key);
- Utils.checkNotNull(iv);
-
- int cipherMode = javax.crypto.Cipher.DECRYPT_MODE;
- if (mode == ENCRYPT_MODE)
- cipherMode = javax.crypto.Cipher.ENCRYPT_MODE;
-
- cipher.init(cipherMode, new SecretKeySpec(key, "AES"),
- new IvParameterSpec(iv));
- }
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data
- * is encrypted or decrypted, depending on how this cipher was initialized.
- *
- * @param inBuffer the input ByteBuffer
- * @param outBuffer the output ByteBuffer
- * @return int number of bytes stored in <code>output</code>
- * @throws ShortBufferException if there is insufficient space
- * in the output buffer
- */
- @Override
- public int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
- throws ShortBufferException {
- return cipher.update(inBuffer, outBuffer);
- }
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data
- * is encrypted or decrypted, depending on how this cipher was initialized.
- *
- * @param input the input byte array
- * @param inputOffset the offset in input where the input starts
- * @param inputLen the input length
- * @param output the byte array for the result
- * @param outputOffset the offset in output where the result is stored
- * @return the number of bytes stored in output
- * @throws ShortBufferException if there is insufficient space in the output byte array
- */
- @Override
- public int update(byte[] input, int inputOffset, int inputLen,
- byte[] output, int outputOffset)
- throws ShortBufferException {
- return cipher.update(input, inputOffset, inputLen,
- output, outputOffset);
- }
-
- /**
- * Encrypts or decrypts data in a single-part operation, or finishes a
- * multiple-part operation. The data is encrypted or decrypted, depending
- * on how this cipher was initialized.
- *
- * @param inBuffer the input ByteBuffer
- * @param outBuffer the output ByteBuffer
- * @return int number of bytes stored in <code>output</code>
- * @throws BadPaddingException if this cipher is in decryption mode,
- * and (un)padding has been requested, but the decrypted data is not
- * bounded by the appropriate padding bytes
- * @throws IllegalBlockSizeException if this cipher is a block cipher,
- * no padding has been requested (only in encryption mode), and the total
- * input length of the data processed by this cipher is not a multiple of
- * block size; or if this encryption algorithm is unable to
- * process the input data provided.
- * @throws ShortBufferException if the given output buffer is too small
- * to hold the result
- */
- @Override
- public int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
- throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException {
- return cipher.doFinal(inBuffer, outBuffer);
- }
-
- /**
- * Encrypts or decrypts data in a single-part operation, or finishes a
- * multiple-part operation.
- *
- * @param input the input byte array
- * @param inputOffset the offset in input where the input starts
- * @param inputLen the input length
- * @param output the byte array for the result
- * @param outputOffset the offset in output where the result is stored
- * @return the number of bytes stored in output
- * @throws ShortBufferException if the given output byte array is too small
- * to hold the result
- * @throws BadPaddingException if this cipher is in decryption mode,
- * and (un)padding has been requested, but the decrypted data is not
- * bounded by the appropriate padding bytes
- * @throws IllegalBlockSizeException if this cipher is a block cipher,
- * no padding has been requested (only in encryption mode), and the total
- * input length of the data processed by this cipher is not a multiple of
- * block size; or if this encryption algorithm is unable to
- * process the input data provided.
- */
- @Override
- public int doFinal(byte[] input, int inputOffset, int inputLen,
- byte[] output, int outputOffset)
- throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
- return cipher.doFinal(input, inputOffset, inputLen,
- output, outputOffset);
- }
-
- /**
- * Closes Jce cipher.
- */
- @Override
- public void close() {
- // Do nothing
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/cipher/Openssl.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/cipher/Openssl.java b/src/main/java/com/intel/chimera/cipher/Openssl.java
deleted file mode 100644
index 8025ceb..0000000
--- a/src/main/java/com/intel/chimera/cipher/Openssl.java
+++ /dev/null
@@ -1,320 +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 com.intel.chimera.cipher;
-
-import java.nio.ByteBuffer;
-import java.security.NoSuchAlgorithmException;
-import java.util.StringTokenizer;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.ShortBufferException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.intel.chimera.utils.NativeCodeLoader;
-import com.intel.chimera.utils.Utils;
-
-/**
- * OpenSSL cryptographic wrapper using JNI.
- * Currently only AES-CTR is supported. It's flexible to add
- * other crypto algorithms/modes.
- */
-public final class Openssl {
- private static final Log LOG = LogFactory.getLog(Openssl.class.getName());
-
- // Mode constant defined by Openssl JNI
- public static final int ENCRYPT_MODE = 1;
- public static final int DECRYPT_MODE = 0;
-
- /** Currently only support AES/CTR/NoPadding. */
- private static enum AlgorithmMode {
- AES_CTR,
- AES_CBC;
-
- static int get(String algorithm, String mode)
- throws NoSuchAlgorithmException {
- try {
- return AlgorithmMode.valueOf(algorithm + "_" + mode).ordinal();
- } catch (Exception e) {
- throw new NoSuchAlgorithmException("Doesn't support algorithm: " +
- algorithm + " and mode: " + mode);
- }
- }
- }
-
- private static enum Padding {
- NoPadding,
- PKCS5Padding;
-
- static int get(String padding) throws NoSuchPaddingException {
- try {
- return Padding.valueOf(padding).ordinal();
- } catch (Exception e) {
- throw new NoSuchPaddingException("Doesn't support padding: " + padding);
- }
- }
- }
-
- private long context = 0;
- private final int algorithm;
- private final int padding;
-
- private static final String loadingFailureReason;
-
- static {
- String loadingFailure = null;
- try {
- if (NativeCodeLoader.isNativeCodeLoaded()) {
- OpensslNative.initIDs();
- }
- } catch (Throwable t) {
- loadingFailure = t.getMessage();
- LOG.debug("Failed to load OpenSSL Cipher.", t);
- } finally {
- loadingFailureReason = loadingFailure;
- }
- }
-
- /**
- * Gets the failure reason when loading Openssl native.
- * @return the failure reason.
- */
- public static String getLoadingFailureReason() {
- return loadingFailureReason;
- }
-
- private Openssl(long context, int algorithm, int padding) {
- this.context = context;
- this.algorithm = algorithm;
- this.padding = padding;
- }
-
- /**
- * Return an <code>OpensslCipher<code> object that implements the specified
- * transformation.
- *
- * @param transformation the name of the transformation, e.g.,
- * AES/CTR/NoPadding.
- * @return OpensslCipher an <code>OpensslCipher<code> object
- * @throws NoSuchAlgorithmException if <code>transformation</code> is null,
- * empty, in an invalid format, or if Openssl doesn't implement the
- * specified algorithm.
- * @throws NoSuchPaddingException if <code>transformation</code> contains
- * a padding scheme that is not available.
- */
- public static final Openssl getInstance(String transformation)
- throws NoSuchAlgorithmException, NoSuchPaddingException {
- Transform transform = tokenizeTransformation(transformation);
- int algorithmMode = AlgorithmMode.get(transform.algorithm, transform.mode);
- int padding = Padding.get(transform.padding);
- long context = OpensslNative.initContext(algorithmMode, padding);
- return new Openssl(context, algorithmMode, padding);
- }
-
- /** Nested class for algorithm, mode and padding. */
- private static class Transform {
- final String algorithm;
- final String mode;
- final String padding;
-
- public Transform(String algorithm, String mode, String padding) {
- this.algorithm = algorithm;
- this.mode = mode;
- this.padding = padding;
- }
- }
-
- private static Transform tokenizeTransformation(String transformation)
- throws NoSuchAlgorithmException {
- if (transformation == null) {
- throw new NoSuchAlgorithmException("No transformation given.");
- }
-
- /*
- * Array containing the components of a Cipher transformation:
- *
- * index 0: algorithm (e.g., AES)
- * index 1: mode (e.g., CTR)
- * index 2: padding (e.g., NoPadding)
- */
- String[] parts = new String[3];
- int count = 0;
- StringTokenizer parser = new StringTokenizer(transformation, "/");
- while (parser.hasMoreTokens() && count < 3) {
- parts[count++] = parser.nextToken().trim();
- }
- if (count != 3 || parser.hasMoreTokens()) {
- throw new NoSuchAlgorithmException("Invalid transformation format: " +
- transformation);
- }
- return new Transform(parts[0], parts[1], parts[2]);
- }
-
- /**
- * Initialize this cipher with a key and IV.
- *
- * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
- * @param key crypto key
- * @param iv crypto iv
- */
- public void init(int mode, byte[] key, byte[] iv) {
- context = OpensslNative.init(context, mode, algorithm, padding, key, iv);
- }
-
- /**
- * Continues a multiple-part encryption or decryption operation. The data
- * is encrypted or decrypted, depending on how this cipher was initialized.
- * <p/>
- *
- * All <code>input.remaining()</code> bytes starting at
- * <code>input.position()</code> are processed. The result is stored in
- * the output buffer.
- * <p/>
- *
- * Upon return, the input buffer's position will be equal to its limit;
- * its limit will not have changed. The output buffer's position will have
- * advanced by n, when n is the value returned by this method; the output
- * buffer's limit will not have changed.
- * <p/>
- *
- * If <code>output.remaining()</code> bytes are insufficient to hold the
- * result, a <code>ShortBufferException</code> is thrown.
- *
- * @param input the input ByteBuffer
- * @param output the output ByteBuffer
- * @return int number of bytes stored in <code>output</code>
- * @throws ShortBufferException if there is insufficient space in the
- * output buffer
- */
- public int update(ByteBuffer input, ByteBuffer output)
- throws ShortBufferException {
- checkState();
- Utils.checkArgument(input.isDirect() && output.isDirect(),
- "Direct buffers are required.");
- int len = OpensslNative.update(context, input, input.position(),
- input.remaining(), output, output.position(), output.remaining());
- input.position(input.limit());
- output.position(output.position() + len);
- return len;
- }
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data
- * is encrypted or decrypted, depending on how this cipher was initialized.
- *
- * @param input the input byte array
- * @param inputOffset the offset in input where the input starts
- * @param inputLen the input length
- * @param output the byte array for the result
- * @param outputOffset the offset in output where the result is stored
- * @return the number of bytes stored in output
- * @throws ShortBufferException if there is insufficient space in the output byte array
- */
- public int update(byte[] input, int inputOffset, int inputLen,
- byte[] output, int outputOffset)
- throws ShortBufferException {
- checkState();
- return OpensslNative.updateByteArray(context, input, inputOffset, inputLen,
- output, outputOffset, output.length - outputOffset);
- }
-
- /**
- * Finishes a multiple-part operation. The data is encrypted or decrypted,
- * depending on how this cipher was initialized.
- * <p/>
- *
- * The result is stored in the output buffer. Upon return, the output buffer's
- * position will have advanced by n, where n is the value returned by this
- * method; the output buffer's limit will not have changed.
- * <p/>
- *
- * If <code>output.remaining()</code> bytes are insufficient to hold the result,
- * a <code>ShortBufferException</code> is thrown.
- * <p/>
- *
- * Upon finishing, this method resets this cipher object to the state it was
- * in when previously initialized. That is, the object is available to encrypt
- * or decrypt more data.
- * <p/>
- *
- * If any exception is thrown, this cipher object need to be reset before it
- * can be used again.
- *
- * @param output the output ByteBuffer
- * @return int number of bytes stored in <code>output</code>
- * @throws ShortBufferException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- public int doFinal(ByteBuffer output)
- throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException {
- checkState();
- Utils.checkArgument(output.isDirect(), "Direct buffer is required.");
- int len = OpensslNative.doFinal(context, output, output.position(), output.remaining());
- output.position(output.position() + len);
- return len;
- }
-
- /**
- * Encrypts or decrypts data in a single-part operation, or finishes a
- * multiple-part operation.
- *
- * @param output the byte array for the result
- * @param outputOffset the offset in output where the result is stored
- * @return the number of bytes stored in output
- * @throws ShortBufferException if the given output byte array is too small
- * to hold the result
- * @throws BadPaddingException if this cipher is in decryption mode,
- * and (un)padding has been requested, but the decrypted data is not
- * bounded by the appropriate padding bytes
- * @throws IllegalBlockSizeException if this cipher is a block cipher,
- * no padding has been requested (only in encryption mode), and the total
- * input length of the data processed by this cipher is not a multiple of
- * block size; or if this encryption algorithm is unable to
- * process the input data provided.
- */
- public int doFinal(byte[] output, int outputOffset)
- throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
- checkState();
- return OpensslNative.doFinalByteArray(context,
- output, outputOffset, output.length - outputOffset);
- }
-
- /** Forcibly clean the context. */
- public void clean() {
- if (context != 0) {
- OpensslNative.clean(context);
- context = 0;
- }
- }
-
- /** Checks whether context is initialized. */
- private void checkState() {
- Utils.checkState(context != 0);
- }
-
- @Override
- protected void finalize() throws Throwable {
- clean();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/cipher/OpensslCipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/cipher/OpensslCipher.java b/src/main/java/com/intel/chimera/cipher/OpensslCipher.java
deleted file mode 100644
index 6e39c84..0000000
--- a/src/main/java/com/intel/chimera/cipher/OpensslCipher.java
+++ /dev/null
@@ -1,196 +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 com.intel.chimera.cipher;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.util.Properties;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-
-import com.intel.chimera.utils.Utils;
-
-/**
- * Implements the Cipher using JNI into OpenSSL.
- */
-public class OpensslCipher implements Cipher {
- private final Properties props;
- private final CipherTransformation transformation;
- private final Openssl cipher;
-
- /**
- * Constructs a {@link com.intel.chimera.cipher.Cipher} using JNI into OpenSSL
- *
- * @param props properties for OpenSSL cipher
- * @param transformation transformation for OpenSSL cipher
- * @throws GeneralSecurityException if OpenSSL cipher initialize failed
- */
- public OpensslCipher(Properties props, CipherTransformation transformation)
- throws GeneralSecurityException {
- this.props = props;
- this.transformation = transformation;
-
- String loadingFailureReason = Openssl.getLoadingFailureReason();
- if (loadingFailureReason != null) {
- throw new RuntimeException(loadingFailureReason);
- }
-
- cipher = Openssl.getInstance(transformation.getName());
- }
-
- /**
- * Gets the CipherTransformation for the openssl cipher.
- *
- * @return the CipherTransformation for this cipher
- */
- @Override
- public CipherTransformation getTransformation() {
- return transformation;
- }
-
- /**
- * Gets the properties for the openssl cipher.
- *
- * @return the properties for this cipher.
- */
- @Override
- public Properties getProperties() {
- return props;
- }
-
- /**
- * Initializes the cipher with mode, key and iv.
- * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
- * @param key crypto key for the cipher
- * @param iv Initialization vector for the cipher
- * @throws IOException if cipher initialize fails
- */
- @Override
- public void init(int mode, byte[] key, byte[] iv) {
- Utils.checkNotNull(key);
- Utils.checkNotNull(iv);
-
- int cipherMode = Openssl.DECRYPT_MODE;
- if (mode == ENCRYPT_MODE)
- cipherMode = Openssl.ENCRYPT_MODE;
-
- cipher.init(cipherMode, key, iv);
- }
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data
- * is encrypted or decrypted, depending on how this cipher was initialized.
- * @param inBuffer the input ByteBuffer
- * @param outBuffer the output ByteBuffer
- * @return int number of bytes stored in <code>output</code>
- * @throws ShortBufferException if there is insufficient space
- * in the output buffer
- */
- @Override
- public int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
- throws ShortBufferException {
- return cipher.update(inBuffer, outBuffer);
- }
-
- /**
- * Continues a multiple-part encryption/decryption operation. The data
- * is encrypted or decrypted, depending on how this cipher was initialized.
- *
- * @param input the input byte array
- * @param inputOffset the offset in input where the input starts
- * @param inputLen the input length
- * @param output the byte array for the result
- * @param outputOffset the offset in output where the result is stored
- * @return the number of bytes stored in output
- * @throws ShortBufferException if there is insufficient space in the output byte array
- */
- @Override
- public int update(byte[] input, int inputOffset, int inputLen,
- byte[] output, int outputOffset)
- throws ShortBufferException {
- return cipher.update(input, inputOffset, inputLen,
- output, outputOffset);
- }
-
- /**
- * Encrypts or decrypts data in a single-part operation, or finishes a
- * multiple-part operation. The data is encrypted or decrypted, depending
- * on how this cipher was initialized.
- * @param inBuffer the input ByteBuffer
- * @param outBuffer the output ByteBuffer
- * @return int number of bytes stored in <code>output</code>
- * @throws BadPaddingException if this cipher is in decryption mode,
- * and (un)padding has been requested, but the decrypted data is not
- * bounded by the appropriate padding bytes
- * @throws IllegalBlockSizeException if this cipher is a block cipher,
- * no padding has been requested (only in encryption mode), and the total
- * input length of the data processed by this cipher is not a multiple of
- * block size; or if this encryption algorithm is unable to
- * process the input data provided.
- * @throws ShortBufferException if the given output buffer is too small
- * to hold the result
- */
- @Override
- public int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
- throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException {
- int n = cipher.update(inBuffer, outBuffer);
- return n + cipher.doFinal(outBuffer);
- }
-
- /**
- * Encrypts or decrypts data in a single-part operation, or finishes a
- * multiple-part operation.
- *
- * @param input the input byte array
- * @param inputOffset the offset in input where the input starts
- * @param inputLen the input length
- * @param output the byte array for the result
- * @param outputOffset the offset in output where the result is stored
- * @return the number of bytes stored in output
- * @throws ShortBufferException if the given output byte array is too small
- * to hold the result
- * @throws BadPaddingException if this cipher is in decryption mode,
- * and (un)padding has been requested, but the decrypted data is not
- * bounded by the appropriate padding bytes
- * @throws IllegalBlockSizeException if this cipher is a block cipher,
- * no padding has been requested (only in encryption mode), and the total
- * input length of the data processed by this cipher is not a multiple of
- * block size; or if this encryption algorithm is unable to
- * process the input data provided.
- */
- @Override
- public int doFinal(byte[] input, int inputOffset, int inputLen,
- byte[] output, int outputOffset)
- throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
- int n = cipher.update(input, inputOffset, inputLen,
- output, outputOffset);
- return n + cipher.doFinal(output, outputOffset + n);
- }
-
- /**
- * Closes the OpenSSL cipher. Clean the Openssl native context.
- */
- @Override
- public void close() {
- cipher.clean();
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/cipher/OpensslNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/cipher/OpensslNative.java b/src/main/java/com/intel/chimera/cipher/OpensslNative.java
deleted file mode 100644
index ed209e8..0000000
--- a/src/main/java/com/intel/chimera/cipher/OpensslNative.java
+++ /dev/null
@@ -1,116 +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 com.intel.chimera.cipher;
-
-import java.nio.ByteBuffer;
-
-/**
- * JNI interface of {@link Openssl} implementation. The native method in this class is
- * defined in OpensslNative.h(genereted by javah).
- */
-public class 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.
- *
- * @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/4920d272/src/main/java/com/intel/chimera/cipher/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/cipher/package-info.java b/src/main/java/com/intel/chimera/cipher/package-info.java
deleted file mode 100644
index 80a2c8f..0000000
--- a/src/main/java/com/intel/chimera/cipher/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-
-/**
- * Cipher classes
- */
-package com.intel.chimera.cipher;
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/conf/ConfigurationKeys.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/conf/ConfigurationKeys.java b/src/main/java/com/intel/chimera/conf/ConfigurationKeys.java
deleted file mode 100644
index 4058636..0000000
--- a/src/main/java/com/intel/chimera/conf/ConfigurationKeys.java
+++ /dev/null
@@ -1,139 +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 com.intel.chimera.conf;
-
-import com.intel.chimera.cipher.JceCipher;
-
-/**
- * The ConfigurationKeys contains Configuration keys and default values.
- */
-public class ConfigurationKeys {
-
- /**
- * The prefix named with project name.
- */
- public static final String CHIMERA_PREFIX = "chimera.";
-
- /**
- * The filename of configuration file.
- */
- public static final String CHIMERA_SYSTEM_PROPERTIES_FILE =
- CHIMERA_PREFIX + "properties";
-
- /**
- * The prefix of crypto configuration.
- */
- public static final String CONF_PREFIX =
- CHIMERA_PREFIX + "crypto.";
-
- /**
- * The configuration key of implementation class for crypto cipher.
- * The values of CHIMERA_CRYPTO_CIPHER_CLASSES_KEY can be
- * "com.intel.chimera.cipher.JceCipher" and "com.intel.chimera.cipher.OpensslCipher".
- * And it takes a common separated list.
- * The "com.intel.chimera.cipher.JceCipher" use jce provider to
- * implement {@link com.intel.chimera.cipher.Cipher} and
- * the "com.intel.chimera.cipher.OpensslCipher" use jni into openssl to implement.
- * Note that for each value,the first value which can be created without exception
- * will be used (priority by order).
- */
- public static final String CHIMERA_CRYPTO_CIPHER_CLASSES_KEY =
- CONF_PREFIX + "cipher.classes";
-
- /**
- * The default value for crypto cipher.
- */
- public static final String CHIMERA_CRYPTO_CIPHER_CLASSES_DEFAULT =
- JceCipher.class.getName();
-
- /**
- * The configuration key of the provider class for JCE cipher.
- */
- public static final String CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY =
- CONF_PREFIX + "cipher.jce.provider";
-
- // security random related configuration keys
- /**
- * The configuration key of the file path for secure random device.
- */
- public static final String CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY =
- CONF_PREFIX + "secure.random.device.file.path";
-
- /**
- * The default value of the file path for secure random device.
- */
- public static final String CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT =
- "/dev/urandom";
-
- /**
- * The configuration key of the algorithm of secure random.
- */
- public static final String CHIMERA_CRYPTO_SECURE_RANDOM_JAVA_ALGORITHM_KEY =
- CONF_PREFIX + "secure.random.java.algorithm";
-
- /**
- * The default value of the algorithm of secure random.
- */
- public static final String
- CHIMERA_CRYPTO_SECURE_RANDOM_JAVA_ALGORITHM_DEFAULT = "SHA1PRNG";
-
- /**
- * The configuration key of the implementation class for secure random.
- * The values of CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY can be
- * "com.intel.chimera.random.JavaSecureRandom" and "com.intel.chimera.random.OpensslSecureRandom".
- * And it takes a common separated list.
- * The "com.intel.chimera.random.JavaSecureRandom" use java to
- * implement {@link com.intel.chimera.random.SecureRandom} and
- * the "com.intel.chimera.random.OpensslSecureRandom" use jni into openssl to implement.
- * Note that for each value,the first value which can be created without exception
- * will be used (priority by order).
- */
- public static final String CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY =
- CONF_PREFIX + "secure.random.classes";
-
- /**
- * The configuration key of the buffer size for stream.
- */
- public static final String CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY =
- CONF_PREFIX + "stream.buffer.size";
-
- // stream related configuration keys
- /**
- * The default value of the buffer size for stream.
- */
- public static final int CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_DEFAULT = 8192;
-
- // native lib related configuration keys
- /**
- * The configuration key of the path for loading crypto library.
- */
- public static final String CHIMERA_CRYPTO_LIB_PATH_KEY =
- CONF_PREFIX + "lib.path";
-
- /**
- * The configuration key of the file name for loading crypto library.
- */
- public static final String CHIMERA_CRYPTO_LIB_NAME_KEY =
- CONF_PREFIX + "lib.name";
-
- /**
- * The configuration key of temp directory for extracting crypto library.
- */
- public static final String CHIMERA_CRYPTO_LIB_TEMPDIR_KEY =
- CONF_PREFIX + "lib.tempdir";
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/conf/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/conf/package-info.java b/src/main/java/com/intel/chimera/conf/package-info.java
deleted file mode 100644
index d9cd2b8..0000000
--- a/src/main/java/com/intel/chimera/conf/package-info.java
+++ /dev/null
@@ -1,21 +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.
- */
-/**
- * Configuration classes
- */
-package com.intel.chimera.conf;
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/random/JavaSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/random/JavaSecureRandom.java b/src/main/java/com/intel/chimera/random/JavaSecureRandom.java
deleted file mode 100644
index ec4063d..0000000
--- a/src/main/java/com/intel/chimera/random/JavaSecureRandom.java
+++ /dev/null
@@ -1,73 +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 com.intel.chimera.random;
-
-import java.security.NoSuchAlgorithmException;
-import java.util.Properties;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.intel.chimera.conf.ConfigurationKeys;
-
-/**
- * A SecureRandom of Java implementation.
- */
-public class JavaSecureRandom implements SecureRandom {
- private static final Log LOG =
- LogFactory.getLog(JavaSecureRandom.class.getName());
-
- private java.security.SecureRandom instance;
-
- /**
- * Constructs a {@link com.intel.chimera.random.JavaSecureRandom}.
- *
- * @param properties the configuration properties.
- */
- public JavaSecureRandom(Properties properties) {
- try {
- instance = java.security.SecureRandom
- .getInstance(properties.getProperty(
- ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_JAVA_ALGORITHM_KEY,
- ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_JAVA_ALGORITHM_DEFAULT));
- } catch (NoSuchAlgorithmException e) {
- LOG.error("Failed to create java secure random due to error: " + e);
- }
- }
-
- /**
- * Overrides {@link java.lang.AutoCloseable#close()}.
- * For{@link JavaSecureRandom}, we don't need to recycle resource.
- */
- @Override
- public void close() {
- // do nothing
- }
-
- /**
- * Overrides {@link com.intel.chimera.random.SecureRandom#nextBytes(byte[])}.
- * Generates random bytes and places them into a user-supplied byte array.
- * The number of random bytes produced is equal to the length of the byte array.
- *
- * @param bytes the array to be filled in with random bytes.
- */
- @Override
- public void nextBytes(byte[] bytes) {
- instance.nextBytes(bytes);
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/random/OpensslSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/random/OpensslSecureRandom.java b/src/main/java/com/intel/chimera/random/OpensslSecureRandom.java
deleted file mode 100644
index bbf0f86..0000000
--- a/src/main/java/com/intel/chimera/random/OpensslSecureRandom.java
+++ /dev/null
@@ -1,140 +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 com.intel.chimera.random;
-
-import java.util.Properties;
-import java.util.Random;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.intel.chimera.utils.NativeCodeLoader;
-import com.intel.chimera.utils.Utils;
-
-/**
- * OpenSSL secure random using JNI.
- * This implementation is thread-safe.
- * <p/>
- *
- * If using an Intel chipset with RDRAND, the high-performance hardware
- * random number generator will be used and it's much faster than
- * {@link java.security.SecureRandom}. If RDRAND is unavailable, default
- * OpenSSL secure random generator will be used. It's still faster
- * and can generate strong random bytes.
- * <p/>
- * @see https://wiki.openssl.org/index.php/Random_Numbers
- * @see http://en.wikipedia.org/wiki/RdRand
- */
-public class OpensslSecureRandom extends Random implements SecureRandom {
- private static final long serialVersionUID = -7828193502768789584L;
- private static final Log LOG =
- LogFactory.getLog(OpensslSecureRandom.class.getName());
-
- /** If native SecureRandom unavailable, use java SecureRandom */
- private JavaSecureRandom fallback = null;
- private static boolean nativeEnabled = false;
- static {
- if (NativeCodeLoader.isNativeCodeLoaded()) {
- try {
- OpensslSecureRandomNative.initSR();
- nativeEnabled = true;
- } catch (Throwable t) {
- LOG.error("Failed to load Openssl SecureRandom", t);
- }
- }
- }
-
- /**
- * Judges whether loading native library successfully.
- *
- * @return true if loading library successfully.
- */
- public static boolean isNativeCodeLoaded() {
- return nativeEnabled;
- }
-
- /**
- * Constructs a {@link com.intel.chimera.random.OpensslSecureRandom}.
- *
- * @param props the configuration properties.
- */
- public OpensslSecureRandom(Properties props) {
- if (!nativeEnabled) {
- fallback = new JavaSecureRandom(props);
- }
- }
-
- /**
- * Generates a user-specified number of random bytes.
- * It's thread-safe.
- *
- * @param bytes the array to be filled in with random bytes.
- */
- @Override
- public void nextBytes(byte[] bytes) {
- if (!nativeEnabled || !OpensslSecureRandomNative.nextRandBytes(bytes)) {
- fallback.nextBytes(bytes);
- }
- }
-
- /**
- * Overrides {@link OpensslSecureRandom}.
- * For {@link OpensslSecureRandom}, we don't need to set seed.
- *
- * @param seed the initial seed.
- */
- @Override
- public void setSeed(long seed) {
- // Self-seeding.
- }
-
- /**
- * Overrides {@link java.util.Random# next()}. Generates an integer
- * containing the user-specified number of random
- * bits(right justified, with leading zeros).
- *
- * @param numBits number of random bits to be generated, where
- * 0 <= <code>numBits</code> <= 32.
- * @return int an <code>int</code> containing the user-specified number
- * of random bits (right justified, with leading zeros).
- */
- @Override
- final protected int next(int numBits) {
- Utils.checkArgument(numBits >= 0 && numBits <= 32);
- int numBytes = (numBits + 7) / 8;
- byte b[] = new byte[numBytes];
- int next = 0;
-
- nextBytes(b);
- for (int i = 0; i < numBytes; i++) {
- next = (next << 8) + (b[i] & 0xFF);
- }
-
- return next >>> (numBytes * 8 - numBits);
- }
-
- /**
- * Overrides {@link java.lang.AutoCloseable#close()}. Closes openssl context if native enabled.
- */
- @Override
- public void close() {
- if (!nativeEnabled && fallback !=null) {
- fallback.close();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/random/OpensslSecureRandomNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/random/OpensslSecureRandomNative.java b/src/main/java/com/intel/chimera/random/OpensslSecureRandomNative.java
deleted file mode 100644
index 69f61ff..0000000
--- a/src/main/java/com/intel/chimera/random/OpensslSecureRandomNative.java
+++ /dev/null
@@ -1,40 +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 com.intel.chimera.random;
-
-/**
- * JNI interface of {@link SecureRandom} implementation.
- * The native method in this class is defined in
- * OpensslSecureRandomNative.h(genereted by javah).
- */
-public class OpensslSecureRandomNative {
- /**
- * Declares a native method to initialize SR.
- */
- public native static void initSR();
-
- /**
- * Judges whether use {@link OpensslSecureRandomNative} 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 OpensslSecureRandomNative} to
- * generate the user-specified number of random bits.
- */
- public native static boolean nextRandBytes(byte[] bytes);
-}
[3/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
Posted by xu...@apache.org.
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/cipher/OpensslNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/cipher/OpensslNative.c b/src/main/native/com/intel/chimera/cipher/OpensslNative.c
deleted file mode 100644
index 4f87866..0000000
--- a/src/main/native/com/intel/chimera/cipher/OpensslNative.c
+++ /dev/null
@@ -1,467 +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 "com_intel_chimera.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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_com_intel_chimera_cipher_OpensslNative_initIDs
- (JNIEnv *env, jclass clazz)
-{
- char msg[1000];
-#ifdef UNIX
- openssl = dlopen(CHIMERA_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
-#endif
-
-#ifdef WINDOWS
- openssl = LoadLibrary(CHIMERA_OPENSSL_LIBRARY);
-#endif
-
- if (!openssl) {
- snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", CHIMERA_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_com_intel_chimera_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_com_intel_chimera_cipher_OpensslNative_init
- (JNIEnv *env, jclass clazz, jlong ctx, jint mode, jint alg, jint padding,
- jbyteArray key, jbyteArray iv)
-{
- 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) {
- THROW(env, "java/security/InvalidKeyException", "Invalid key length.");
- return (jlong)0;
- }
- if (jIvLen != IV_LENGTH) {
- THROW(env, "java/security/InvalidAlgorithmParameterException", "Wrong IV length.");
- return (jlong)0;
- }
-
- EVP_CIPHER_CTX *context = CONTEXT(ctx);
- 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;
- }
- }
-
- jbyte *jKey = (*env)->GetByteArrayElements(env, key, NULL);
- if (jKey == NULL) {
- THROW(env, "java/lang/InternalError", "Cannot get bytes array for key.");
- return (jlong)0;
- }
- jbyte *jIv = (*env)->GetByteArrayElements(env, iv, NULL);
- if (jIv == NULL) {
- (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
- THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
- return (jlong)0;
- }
-
- if (!(alg == AES_CTR || alg == AES_CBC)) {
- THROW(env, "java/security/NoSuchAlgorithmException", "The algorithm is not supported.");
- return (jlong)0;
- }
-
- int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen), \
- NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
- (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
- (*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
- if (rc == 0) {
- dlsym_EVP_CIPHER_CTX_cleanup(context);
- THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
- return (jlong)0;
- }
-
- if (padding == NOPADDING) {
- dlsym_EVP_CIPHER_CTX_set_padding(context, 0);
- } else if (padding == PKCS5PADDING) {
- dlsym_EVP_CIPHER_CTX_set_padding(context, 1);
- }
-
- return JLONG(context);
-}
-
-// 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_com_intel_chimera_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_com_intel_chimera_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 = (unsigned char *) (*env)->GetByteArrayElements(env, input, 0);
- unsigned char *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.");
- return 0;
- }
-
- int output_len = 0;
- int rc = dlsym_EVP_CipherUpdate(context, output_bytes + output_offset, &output_len, \
- input_bytes + input_offset, input_len);
-
- (*env)->ReleaseByteArrayElements(env, input, (jbyte *) input_bytes, 0);
- (*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_CipherUpdate.");
- return 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_com_intel_chimera_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_com_intel_chimera_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_com_intel_chimera_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/4920d272/src/main/native/com/intel/chimera/com_intel_chimera.h
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/com_intel_chimera.h b/src/main/native/com/intel/chimera/com_intel_chimera.h
deleted file mode 100644
index 1eb979e..0000000
--- a/src/main/native/com/intel/chimera/com_intel_chimera.h
+++ /dev/null
@@ -1,228 +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.
- */
-
-/**
- * This file includes some common utilities
- * for all native code used in chimera.
- */
-
-#if !defined COM_INTEL_CHIMERA_H
-#define COM_INTEL_CHIMERA_H
-
-#if defined(_WIN32)
-#undef UNIX
-#define WINDOWS
-#else
-#undef WINDOWS
-#define UNIX
-#endif
-
-/* A helper macro to 'throw' a java exception. */
-#define THROW(env, exception_name, message) \
- { \
- jclass ecls = (*env)->FindClass(env, exception_name); \
- if (ecls) { \
- (*env)->ThrowNew(env, ecls, message); \
- (*env)->DeleteLocalRef(env, ecls); \
- } \
- }
-
-/* Helper macro to return if an exception is pending */
-#define PASS_EXCEPTIONS(env) \
- { \
- if ((*env)->ExceptionCheck(env)) return; \
- }
-
-#define PASS_EXCEPTIONS_GOTO(env, target) \
- { \
- if ((*env)->ExceptionCheck(env)) goto target; \
- }
-
-#define PASS_EXCEPTIONS_RET(env, ret) \
- { \
- if ((*env)->ExceptionCheck(env)) return (ret); \
- }
-
-/**
- * Unix definitions
- */
-#ifdef UNIX
-#include <config.h>
-#include <dlfcn.h>
-#include <jni.h>
-
-/**
- * A helper function to dlsym a 'symbol' from a given library-handle.
- *
- * @param env jni handle to report contingencies.
- * @param handle handle to the dlopen'ed library.
- * @param symbol symbol to load.
- * @return returns the address where the symbol is loaded in memory,
- * <code>NULL</code> on error.
- */
-static __attribute__ ((unused))
-void *do_dlsym(JNIEnv *env, void *handle, const char *symbol) {
- if (!env || !handle || !symbol) {
- THROW(env, "java/lang/InternalError", NULL);
- return NULL;
- }
- char *error = NULL;
- void *func_ptr = dlsym(handle, symbol);
- if ((error = dlerror()) != NULL) {
- THROW(env, "java/lang/UnsatisfiedLinkError", symbol);
- return NULL;
- }
- return func_ptr;
-}
-
-/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
-#define LOAD_DYNAMIC_SYMBOL(func_ptr, env, handle, symbol) \
- if ((func_ptr = do_dlsym(env, handle, symbol)) == NULL) { \
- return; \
- }
-#endif
-// Unix part end
-
-
-/**
- * Windows definitions
- */
-#ifdef WINDOWS
-
-/* Force using Unicode throughout the code */
-#ifndef UNICODE
-#define UNICODE
-#endif
-
-/* Microsoft C Compiler does not support the C99 inline keyword */
-#ifndef __cplusplus
-#define inline __inline;
-#endif // _cplusplus
-
-/* Optimization macros supported by GCC but for which there is no
- direct equivalent in the Microsoft C compiler */
-#define likely(_c) (_c)
-#define unlikely(_c) (_c)
-
-/* Disable certain warnings in the native CRC32 code. */
-#pragma warning(disable:4018) // Signed/unsigned mismatch.
-#pragma warning(disable:4244) // Possible loss of data in conversion.
-#pragma warning(disable:4267) // Possible loss of data.
-#pragma warning(disable:4996) // Use of deprecated function.
-
-#include <Windows.h>
-#include <stdio.h>
-#include <jni.h>
-
-#define snprintf(a, b ,c, d) _snprintf_s((a), (b), _TRUNCATE, (c), (d))
-
-/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
-#define LOAD_DYNAMIC_SYMBOL(func_type, func_ptr, env, handle, symbol) \
- if ((func_ptr = (func_type) do_dlsym(env, handle, symbol)) == NULL) { \
- return; \
- }
-
-/**
- * A helper function to dynamic load a 'symbol' from a given library-handle.
- *
- * @param env jni handle to report contingencies.
- * @param handle handle to the dynamic library.
- * @param symbol symbol to load.
- * @return returns the address where the symbol is loaded in memory,
- * <code>NULL</code> on error.
- */
-static FARPROC WINAPI do_dlsym(JNIEnv *env, HMODULE handle, LPCSTR symbol) {
- DWORD dwErrorCode = ERROR_SUCCESS;
- FARPROC func_ptr = NULL;
-
- if (!env || !handle || !symbol) {
- THROW(env, "java/lang/InternalError", NULL);
- return NULL;
- }
-
- func_ptr = GetProcAddress(handle, symbol);
- if (func_ptr == NULL)
- {
- THROW(env, "java/lang/UnsatisfiedLinkError", symbol);
- }
- return func_ptr;
-}
-#endif
-// Windows part end
-
-
-#define LOCK_CLASS(env, clazz, classname) \
- if ((*env)->MonitorEnter(env, clazz) != 0) { \
- char exception_msg[128]; \
- snprintf(exception_msg, 128, "Failed to lock %s", classname); \
- THROW(env, "java/lang/InternalError", exception_msg); \
- }
-
-#define UNLOCK_CLASS(env, clazz, classname) \
- if ((*env)->MonitorExit(env, clazz) != 0) { \
- char exception_msg[128]; \
- snprintf(exception_msg, 128, "Failed to unlock %s", classname); \
- THROW(env, "java/lang/InternalError", exception_msg); \
- }
-
-#define RETRY_ON_EINTR(ret, expr) do { \
- ret = expr; \
-} while ((ret == -1) && (errno == EINTR));
-
-#ifdef UNIX
-#include <dlfcn.h>
-#include "config.h"
-#endif
-
-#ifdef WINDOWS
-#include "winutils.h"
-#endif
-
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-
-/**
- * A helper macro to convert the java 'context-handle'
- * to a EVP_CIPHER_CTX pointer.
- */
-#define CONTEXT(context) ((EVP_CIPHER_CTX*)((ptrdiff_t)(context)))
-
-/**
- * A helper macro to convert the EVP_CIPHER_CTX pointer to the
- * java 'context-handle'.
- */
-#define JLONG(context) ((jlong)((ptrdiff_t)(context)))
-
-#define KEY_LENGTH_128 16
-#define KEY_LENGTH_192 24
-#define KEY_LENGTH_256 32
-#define IV_LENGTH 16
-
-#define ENCRYPT_MODE 1
-#define DECRYPT_MODE 0
-
-/** Currently only support AES/CTR/NoPadding. */
-#define AES_CTR 0
-#define AES_CBC 1
-#define NOPADDING 0
-#define PKCS5PADDING 1
-
-#endif
-
-//vim: sw=2: ts=2: et
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/exception.c
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/exception.c b/src/main/native/com/intel/chimera/exception.c
deleted file mode 100644
index fc072e8..0000000
--- a/src/main/native/com/intel/chimera/exception.c
+++ /dev/null
@@ -1,124 +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 "exception.h"
-
-#include <jni.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-jthrowable newExceptionV(JNIEnv* env, const char *name,
- const char *fmt, va_list ap)
-{
- int need;
- char buf[1], *msg = NULL;
- va_list ap2;
- jstring jstr = NULL;
- jthrowable jthr;
- jclass clazz;
- jmethodID excCtor;
-
- va_copy(ap2, ap);
- clazz = (*env)->FindClass(env, name);
- if (!clazz) {
- jthr = (*env)->ExceptionOccurred(env);
- (*env)->ExceptionClear(env);
- goto done;
- }
- excCtor = (*env)->GetMethodID(env,
- clazz, "<init>", "(Ljava/lang/String;)V");
- if (!excCtor) {
- jthr = (*env)->ExceptionOccurred(env);
- (*env)->ExceptionClear(env);
- goto done;
- }
- need = vsnprintf(buf, sizeof(buf), fmt, ap);
- if (need < 0) {
- fmt = "vsnprintf error";
- need = strlen(fmt);
- }
- msg = malloc(need + 1);
- vsnprintf(msg, need + 1, fmt, ap2);
- jstr = (*env)->NewStringUTF(env, msg);
- if (!jstr) {
- jthr = (*env)->ExceptionOccurred(env);
- (*env)->ExceptionClear(env);
- goto done;
- }
- jthr = (*env)->NewObject(env, clazz, excCtor, jstr);
- if (!jthr) {
- jthr = (*env)->ExceptionOccurred(env);
- (*env)->ExceptionClear(env);
- goto done;
- }
-
-done:
- free(msg);
- va_end(ap2);
- (*env)->DeleteLocalRef(env, jstr);
- return jthr;
-}
-
-jthrowable newException(JNIEnv* env, const char *name, const char *fmt, ...)
-{
- va_list ap;
- jthrowable jthr;
-
- va_start(ap, fmt);
- jthr = newExceptionV(env, name, fmt, ap);
- va_end(ap);
- return jthr;
-}
-
-jthrowable newRuntimeException(JNIEnv* env, const char *fmt, ...)
-{
- va_list ap;
- jthrowable jthr;
-
- va_start(ap, fmt);
- jthr = newExceptionV(env, "java/lang/RuntimeException", fmt, ap);
- va_end(ap);
- return jthr;
-}
-
-jthrowable newIOException(JNIEnv* env, const char *fmt, ...)
-{
- va_list ap;
- jthrowable jthr;
-
- va_start(ap, fmt);
- jthr = newExceptionV(env, "java/io/IOException", fmt, ap);
- va_end(ap);
- return jthr;
-}
-
-const char* terror(int errnum)
-{
-
-#if defined(__sun)
-// MT-Safe under Solaris which doesn't support sys_errlist/sys_nerr
- return strerror(errnum);
-#else
- if ((errnum < 0) || (errnum >= sys_nerr)) {
- return "unknown error.";
- }
- return sys_errlist[errnum];
-#endif
-}
-
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/exception.h
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/exception.h b/src/main/native/com/intel/chimera/exception.h
deleted file mode 100644
index eace346..0000000
--- a/src/main/native/com/intel/chimera/exception.h
+++ /dev/null
@@ -1,104 +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.
- */
-#ifndef CHIMERA_NATIVE_SRC_EXCEPTION_H
-#define CHIMERA_NATIVE_SRC_EXCEPTION_H
-
-#include <jni.h> /* for jthrowable */
-#include <stdarg.h> /* for va_list */
-#include "com_intel_chimera.h"
-
-#ifdef WINDOWS
-/*
- * gcc-style type-checked format arguments are not supported on Windows, so just
- * stub this macro.
- */
-#define TYPE_CHECKED_PRINTF_FORMAT(formatArg, varArgs)
-# else
-/* Use gcc type-checked format arguments. */
-#define TYPE_CHECKED_PRINTF_FORMAT(formatArg, varArgs) \
- __attribute__((format(printf, formatArg, varArgs)))
-#endif
-
-/**
- * Create a new Exception.
- *
- * No exceptions will be pending on return.
- *
- * @param env The JNI environment
- * @param name full name of the Java exception class
- * @param fmt printf-style format string
- * @param ap printf-style arguments
- *
- * @return The RuntimeException
- */
-jthrowable newExceptionV(JNIEnv* env, const char *name,
- const char *fmt, va_list ap);
-
-/**
- * Create a new Exception.
- *
- * No exceptions will be pending on return.
- *
- * @param env The JNI environment
- * @param name full name of the Java exception class
- * @param fmt printf-style format string
- * @param ... printf-style arguments
- *
- * @return The RuntimeException
- */
-jthrowable newException(JNIEnv* env, const char *name, const char *fmt, ...)
- TYPE_CHECKED_PRINTF_FORMAT(3, 4);
-
-/**
- * Create a new RuntimeException.
- *
- * No exceptions will be pending on return.
- *
- * @param env The JNI environment
- * @param fmt printf-style format string
- * @param ... printf-style arguments
- *
- * @return The RuntimeException
- */
-jthrowable newRuntimeException(JNIEnv* env, const char *fmt, ...)
- TYPE_CHECKED_PRINTF_FORMAT(2, 3);
-
-/**
- * Create a new IOException.
- *
- * No exceptions will be pending on return.
- *
- * @param env The JNI environment
- * @param fmt printf-style format string
- * @param ... printf-style arguments
- *
- * @return The IOException, or another exception if we failed
- * to create the NativeIOException.
- */
-jthrowable newIOException(JNIEnv* env, const char *fmt, ...)
- TYPE_CHECKED_PRINTF_FORMAT(2, 3);
-
-/**
- * Thread-safe strerror alternative.
- *
- * @param errnum Error number.
- * @return Statically allocated error string.
- */
-const char* terror(int errnum);
-
-#undef TYPE_CHECKED_PRINTF_FORMAT
-#endif
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/random/OpensslSecureRandomNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/random/OpensslSecureRandomNative.c b/src/main/native/com/intel/chimera/random/OpensslSecureRandomNative.c
deleted file mode 100644
index 96a4fc7..0000000
--- a/src/main/native/com/intel/chimera/random/OpensslSecureRandomNative.c
+++ /dev/null
@@ -1,335 +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 "com_intel_chimera_random.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef UNIX
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#endif
-
-#ifdef WINDOWS
-#include <windows.h>
-#endif
-
-#include "OpensslSecureRandomNative.h"
-
-#ifdef UNIX
-static void * (*dlsym_CRYPTO_malloc) (int, const char *, int);
-static void (*dlsym_CRYPTO_free) (void *);
-static int (*dlsym_CRYPTO_num_locks) (void);
-static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
-static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
-static void (*dlsym_ENGINE_load_rdrand) (void);
-static ENGINE * (*dlsym_ENGINE_by_id) (const char *);
-static int (*dlsym_ENGINE_init) (ENGINE *);
-static int (*dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
-static int (*dlsym_ENGINE_finish) (ENGINE *);
-static int (*dlsym_ENGINE_free) (ENGINE *);
-static void (*dlsym_ENGINE_cleanup) (void);
-static int (*dlsym_RAND_bytes) (unsigned char *, int);
-static unsigned long (*dlsym_ERR_get_error) (void);
-#endif
-
-#ifdef WINDOWS
-typedef void * (__cdecl *__dlsym_CRYPTO_malloc) (int, const char *, int);
-typedef void (__cdecl *__dlsym_CRYPTO_free) (void *);
-typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void);
-typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback) \
- (void (*)(int, int, char *, int);
-typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void);
-typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id) (const char *);
-typedef int (__cdecl *__dlsym_ENGINE_init) (ENGINE *);
-typedef int (__cdecl *__dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
-typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *);
-typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *);
-typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void);
-typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int);
-typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void);
-static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc;
-static __dlsym_CRYPTO_free dlsym_CRYPTO_free;
-static __dlsym_CRYPTO_num_locks dlsym_CRYPTO_num_locks;
-static __dlsym_CRYPTO_set_locking_callback dlsym_CRYPTO_set_locking_callback;
-static __dlsym_ENGINE_load_rdrand dlsym_ENGINE_load_rdrand;
-static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id;
-static __dlsym_ENGINE_init dlsym_ENGINE_init;
-static __dlsym_ENGINE_set_default dlsym_ENGINE_set_default;
-static __dlsym_ENGINE_finish dlsym_ENGINE_finish;
-static __dlsym_ENGINE_free dlsym_ENGINE_free;
-static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup;
-static __dlsym_RAND_bytes dlsym_RAND_bytes;
-static __dlsym_ERR_get_error dlsym_ERR_get_error;
-#endif
-
-static ENGINE * openssl_rand_init(void);
-static void openssl_rand_clean(ENGINE *eng, int clean_locks);
-static int openssl_rand_bytes(unsigned char *buf, int num);
-
-JNIEXPORT void JNICALL Java_com_intel_chimera_random_OpensslSecureRandomNative_initSR
- (JNIEnv *env, jclass clazz)
-{
- char msg[1000];
-#ifdef UNIX
- void *openssl = dlopen(CHIMERA_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
-#endif
-
-#ifdef WINDOWS
- HMODULE openssl = LoadLibrary(CHIMERA_OPENSSL_LIBRARY);
-#endif
-
- if (!openssl) {
- snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", CHIMERA_OPENSSL_LIBRARY, \
- dlerror());
- THROW(env, "java/lang/UnsatisfiedLinkError", msg);
- return;
- }
-
-#ifdef UNIX
- dlerror(); // Clear any existing error
- LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_malloc, env, openssl, "CRYPTO_malloc");
- LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_free, env, openssl, "CRYPTO_free");
- LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks");
- LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback, \
- env, openssl, "CRYPTO_set_locking_callback");
- LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env, \
- openssl, "CRYPTO_set_id_callback");
- LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env, \
- openssl, "ENGINE_load_rdrand");
- LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_by_id, env, openssl, "ENGINE_by_id");
- LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_init, env, openssl, "ENGINE_init");
- LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_set_default, env, \
- openssl, "ENGINE_set_default");
- LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_finish, env, openssl, "ENGINE_finish");
- LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free");
- LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup");
- LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes");
- LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error");
-#endif
-
-#ifdef WINDOWS
- LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_malloc, dlsym_CRYPTO_malloc, \
- env, openssl, "CRYPTO_malloc");
- LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_free, dlsym_CRYPTO_free, \
- env, openssl, "CRYPTO_free");
- LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_num_locks, dlsym_CRYPTO_num_locks, \
- env, openssl, "CRYPTO_num_locks");
- LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_set_locking_callback, \
- dlsym_CRYPTO_set_locking_callback, \
- env, openssl, "CRYPTO_set_locking_callback");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_load_rdrand, dlsym_ENGINE_load_rdrand, \
- env, openssl, "ENGINE_load_rdrand");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id, \
- env, openssl, "ENGINE_by_id");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_init, dlsym_ENGINE_init, \
- env, openssl, "ENGINE_init");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_set_default, dlsym_ENGINE_set_default, \
- env, openssl, "ENGINE_set_default");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_finish, dlsym_ENGINE_finish, \
- env, openssl, "ENGINE_finish");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, \
- env, openssl, "ENGINE_free");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_cleanup, dlsym_ENGINE_cleanup, \
- env, openssl, "ENGINE_cleanup");
- LOAD_DYNAMIC_SYMBOL(__dlsym_RAND_bytes, dlsym_RAND_bytes, \
- env, openssl, "RAND_bytes");
- LOAD_DYNAMIC_SYMBOL(__dlsym_ERR_get_error, dlsym_ERR_get_error, \
- env, openssl, "ERR_get_error");
-#endif
-
- openssl_rand_init();
-}
-
-JNIEXPORT jboolean JNICALL Java_com_intel_chimera_random_OpensslSecureRandomNative_nextRandBytes___3B
- (JNIEnv *env, jobject object, jbyteArray bytes)
-{
- if (NULL == bytes) {
- THROW(env, "java/lang/NullPointerException", "Buffer cannot be null.");
- return JNI_FALSE;
- }
- jbyte *b = (*env)->GetByteArrayElements(env, bytes, NULL);
- if (NULL == b) {
- THROW(env, "java/lang/InternalError", "Cannot get bytes array.");
- return JNI_FALSE;
- }
- int b_len = (*env)->GetArrayLength(env, bytes);
- int ret = openssl_rand_bytes((unsigned char *)b, b_len);
- (*env)->ReleaseByteArrayElements(env, bytes, b, 0);
-
- if (1 != ret) {
- return JNI_FALSE;
- }
- return JNI_TRUE;
-}
-
-/**
- * To ensure thread safety for random number generators, we need to call
- * CRYPTO_set_locking_callback.
- * http://wiki.openssl.org/index.php/Random_Numbers
- * Example: crypto/threads/mttest.c
- */
-
-#ifdef WINDOWS
-static void windows_locking_callback(int mode, int type, char *file, int line);
-static HANDLE *lock_cs;
-
-static void locks_setup(void)
-{
- int i;
- lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE), \
- __FILE__, __LINE__);
-
- for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
- lock_cs[i] = CreateMutex(NULL, FALSE, NULL);
- }
- dlsym_CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) \
- windows_locking_callback);
- /* id callback defined */
-}
-
-static void locks_cleanup(void)
-{
- int i;
- dlsym_CRYPTO_set_locking_callback(NULL);
-
- for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
- CloseHandle(lock_cs[i]);
- }
- dlsym_CRYPTO_free(lock_cs);
-}
-
-static void windows_locking_callback(int mode, int type, char *file, int line)
-{
- UNUSED(file), UNUSED(line);
-
- if (mode & CRYPTO_LOCK) {
- WaitForSingleObject(lock_cs[type], INFINITE);
- } else {
- ReleaseMutex(lock_cs[type]);
- }
-}
-#endif /* WINDOWS */
-
-#ifdef UNIX
-static void pthreads_locking_callback(int mode, int type, char *file, int line);
-static unsigned long pthreads_thread_id(void);
-static pthread_mutex_t *lock_cs;
-
-static void locks_setup(void)
-{
- int i;
- lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * \
- sizeof(pthread_mutex_t), __FILE__, __LINE__);
-
- for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
- pthread_mutex_init(&(lock_cs[i]), NULL);
- }
-
- dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
- dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
-}
-
-static void locks_cleanup(void)
-{
- int i;
- dlsym_CRYPTO_set_locking_callback(NULL);
-
- for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
- pthread_mutex_destroy(&(lock_cs[i]));
- }
-
- dlsym_CRYPTO_free(lock_cs);
-}
-
-static void pthreads_locking_callback(int mode, int type, char *file, int line)
-{
- UNUSED(file), UNUSED(line);
-
- if (mode & CRYPTO_LOCK) {
- pthread_mutex_lock(&(lock_cs[type]));
- } else {
- pthread_mutex_unlock(&(lock_cs[type]));
- }
-}
-
-static unsigned long pthreads_thread_id(void)
-{
- return (unsigned long)syscall(SYS_gettid);
-}
-
-#endif /* UNIX */
-
-/**
- * If using an Intel chipset with RDRAND, the high-performance hardware
- * random number generator will be used.
- */
-static ENGINE * openssl_rand_init(void)
-{
- locks_setup();
-
- dlsym_ENGINE_load_rdrand();
- ENGINE *eng = dlsym_ENGINE_by_id("rdrand");
-
- int ret = -1;
- do {
- if (NULL == eng) {
- break;
- }
-
- int rc = dlsym_ENGINE_init(eng);
- if (0 == rc) {
- break;
- }
-
- rc = dlsym_ENGINE_set_default(eng, ENGINE_METHOD_RAND);
- if (0 == rc) {
- break;
- }
-
- ret = 0;
- } while(0);
-
- if (ret == -1) {
- openssl_rand_clean(eng, 0);
- }
-
- return eng;
-}
-
-static void openssl_rand_clean(ENGINE *eng, int clean_locks)
-{
- if (NULL != eng) {
- dlsym_ENGINE_finish(eng);
- dlsym_ENGINE_free(eng);
- }
-
- dlsym_ENGINE_cleanup();
- if (clean_locks) {
- locks_cleanup();
- }
-}
-
-static int openssl_rand_bytes(unsigned char *buf, int num)
-{
- return dlsym_RAND_bytes(buf, num);
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/random/com_intel_chimera_random.h
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/random/com_intel_chimera_random.h b/src/main/native/com/intel/chimera/random/com_intel_chimera_random.h
deleted file mode 100644
index b011cde..0000000
--- a/src/main/native/com/intel/chimera/random/com_intel_chimera_random.h
+++ /dev/null
@@ -1,40 +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.
- */
-
-#ifndef COM_INTEL_CHIMERA_RANDOM_H
-#define COM_INTEL_CHIMERA_RANDOM_H
-
-#include "com_intel_chimera.h"
-
-#ifdef UNIX
-#include <dlfcn.h>
-#include "config.h"
-#endif
-
-#ifdef WINDOWS
-#include "winutils.h"
-#endif
-
-#define UNUSED(x) ((void)(x))
-
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-
-#endif //COM_INTEL_CHIMERA_RANDOM_H
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/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..552babd
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c
@@ -0,0 +1,467 @@
+/**
+ * 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>
+
+#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(CHIMERA_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+#endif
+
+#ifdef WINDOWS
+ openssl = LoadLibrary(CHIMERA_OPENSSL_LIBRARY);
+#endif
+
+ if (!openssl) {
+ snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", CHIMERA_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)
+{
+ 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) {
+ THROW(env, "java/security/InvalidKeyException", "Invalid key length.");
+ return (jlong)0;
+ }
+ if (jIvLen != IV_LENGTH) {
+ THROW(env, "java/security/InvalidAlgorithmParameterException", "Wrong IV length.");
+ return (jlong)0;
+ }
+
+ EVP_CIPHER_CTX *context = CONTEXT(ctx);
+ 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;
+ }
+ }
+
+ jbyte *jKey = (*env)->GetByteArrayElements(env, key, NULL);
+ if (jKey == NULL) {
+ THROW(env, "java/lang/InternalError", "Cannot get bytes array for key.");
+ return (jlong)0;
+ }
+ jbyte *jIv = (*env)->GetByteArrayElements(env, iv, NULL);
+ if (jIv == NULL) {
+ (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
+ THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
+ return (jlong)0;
+ }
+
+ if (!(alg == AES_CTR || alg == AES_CBC)) {
+ THROW(env, "java/security/NoSuchAlgorithmException", "The algorithm is not supported.");
+ return (jlong)0;
+ }
+
+ int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen), \
+ NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
+ (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
+ (*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
+ if (rc == 0) {
+ dlsym_EVP_CIPHER_CTX_cleanup(context);
+ THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
+ return (jlong)0;
+ }
+
+ if (padding == NOPADDING) {
+ dlsym_EVP_CIPHER_CTX_set_padding(context, 0);
+ } else if (padding == PKCS5PADDING) {
+ dlsym_EVP_CIPHER_CTX_set_padding(context, 1);
+ }
+
+ return JLONG(context);
+}
+
+// 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 = (unsigned char *) (*env)->GetByteArrayElements(env, input, 0);
+ unsigned char *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.");
+ return 0;
+ }
+
+ int output_len = 0;
+ int rc = dlsym_EVP_CipherUpdate(context, output_bytes + output_offset, &output_len, \
+ input_bytes + input_offset, input_len);
+
+ (*env)->ReleaseByteArrayElements(env, input, (jbyte *) input_bytes, 0);
+ (*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_CipherUpdate.");
+ return 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/4920d272/src/main/native/org/apache/commons/crypto/exception.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/exception.c b/src/main/native/org/apache/commons/crypto/exception.c
new file mode 100644
index 0000000..fc072e8
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/exception.c
@@ -0,0 +1,124 @@
+/**
+ * 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 "exception.h"
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+jthrowable newExceptionV(JNIEnv* env, const char *name,
+ const char *fmt, va_list ap)
+{
+ int need;
+ char buf[1], *msg = NULL;
+ va_list ap2;
+ jstring jstr = NULL;
+ jthrowable jthr;
+ jclass clazz;
+ jmethodID excCtor;
+
+ va_copy(ap2, ap);
+ clazz = (*env)->FindClass(env, name);
+ if (!clazz) {
+ jthr = (*env)->ExceptionOccurred(env);
+ (*env)->ExceptionClear(env);
+ goto done;
+ }
+ excCtor = (*env)->GetMethodID(env,
+ clazz, "<init>", "(Ljava/lang/String;)V");
+ if (!excCtor) {
+ jthr = (*env)->ExceptionOccurred(env);
+ (*env)->ExceptionClear(env);
+ goto done;
+ }
+ need = vsnprintf(buf, sizeof(buf), fmt, ap);
+ if (need < 0) {
+ fmt = "vsnprintf error";
+ need = strlen(fmt);
+ }
+ msg = malloc(need + 1);
+ vsnprintf(msg, need + 1, fmt, ap2);
+ jstr = (*env)->NewStringUTF(env, msg);
+ if (!jstr) {
+ jthr = (*env)->ExceptionOccurred(env);
+ (*env)->ExceptionClear(env);
+ goto done;
+ }
+ jthr = (*env)->NewObject(env, clazz, excCtor, jstr);
+ if (!jthr) {
+ jthr = (*env)->ExceptionOccurred(env);
+ (*env)->ExceptionClear(env);
+ goto done;
+ }
+
+done:
+ free(msg);
+ va_end(ap2);
+ (*env)->DeleteLocalRef(env, jstr);
+ return jthr;
+}
+
+jthrowable newException(JNIEnv* env, const char *name, const char *fmt, ...)
+{
+ va_list ap;
+ jthrowable jthr;
+
+ va_start(ap, fmt);
+ jthr = newExceptionV(env, name, fmt, ap);
+ va_end(ap);
+ return jthr;
+}
+
+jthrowable newRuntimeException(JNIEnv* env, const char *fmt, ...)
+{
+ va_list ap;
+ jthrowable jthr;
+
+ va_start(ap, fmt);
+ jthr = newExceptionV(env, "java/lang/RuntimeException", fmt, ap);
+ va_end(ap);
+ return jthr;
+}
+
+jthrowable newIOException(JNIEnv* env, const char *fmt, ...)
+{
+ va_list ap;
+ jthrowable jthr;
+
+ va_start(ap, fmt);
+ jthr = newExceptionV(env, "java/io/IOException", fmt, ap);
+ va_end(ap);
+ return jthr;
+}
+
+const char* terror(int errnum)
+{
+
+#if defined(__sun)
+// MT-Safe under Solaris which doesn't support sys_errlist/sys_nerr
+ return strerror(errnum);
+#else
+ if ((errnum < 0) || (errnum >= sys_nerr)) {
+ return "unknown error.";
+ }
+ return sys_errlist[errnum];
+#endif
+}
+
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/org/apache/commons/crypto/exception.h
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/exception.h b/src/main/native/org/apache/commons/crypto/exception.h
new file mode 100644
index 0000000..2d9a018
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/exception.h
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+#ifndef CHIMERA_NATIVE_SRC_EXCEPTION_H
+#define CHIMERA_NATIVE_SRC_EXCEPTION_H
+
+#include <jni.h> /* for jthrowable */
+#include <stdarg.h> /* for va_list */
+#include "org_apache_commons_crypto.h"
+
+#ifdef WINDOWS
+/*
+ * gcc-style type-checked format arguments are not supported on Windows, so just
+ * stub this macro.
+ */
+#define TYPE_CHECKED_PRINTF_FORMAT(formatArg, varArgs)
+# else
+/* Use gcc type-checked format arguments. */
+#define TYPE_CHECKED_PRINTF_FORMAT(formatArg, varArgs) \
+ __attribute__((format(printf, formatArg, varArgs)))
+#endif
+
+/**
+ * Create a new Exception.
+ *
+ * No exceptions will be pending on return.
+ *
+ * @param env The JNI environment
+ * @param name full name of the Java exception class
+ * @param fmt printf-style format string
+ * @param ap printf-style arguments
+ *
+ * @return The RuntimeException
+ */
+jthrowable newExceptionV(JNIEnv* env, const char *name,
+ const char *fmt, va_list ap);
+
+/**
+ * Create a new Exception.
+ *
+ * No exceptions will be pending on return.
+ *
+ * @param env The JNI environment
+ * @param name full name of the Java exception class
+ * @param fmt printf-style format string
+ * @param ... printf-style arguments
+ *
+ * @return The RuntimeException
+ */
+jthrowable newException(JNIEnv* env, const char *name, const char *fmt, ...)
+ TYPE_CHECKED_PRINTF_FORMAT(3, 4);
+
+/**
+ * Create a new RuntimeException.
+ *
+ * No exceptions will be pending on return.
+ *
+ * @param env The JNI environment
+ * @param fmt printf-style format string
+ * @param ... printf-style arguments
+ *
+ * @return The RuntimeException
+ */
+jthrowable newRuntimeException(JNIEnv* env, const char *fmt, ...)
+ TYPE_CHECKED_PRINTF_FORMAT(2, 3);
+
+/**
+ * Create a new IOException.
+ *
+ * No exceptions will be pending on return.
+ *
+ * @param env The JNI environment
+ * @param fmt printf-style format string
+ * @param ... printf-style arguments
+ *
+ * @return The IOException, or another exception if we failed
+ * to create the NativeIOException.
+ */
+jthrowable newIOException(JNIEnv* env, const char *fmt, ...)
+ TYPE_CHECKED_PRINTF_FORMAT(2, 3);
+
+/**
+ * Thread-safe strerror alternative.
+ *
+ * @param errnum Error number.
+ * @return Statically allocated error string.
+ */
+const char* terror(int errnum);
+
+#undef TYPE_CHECKED_PRINTF_FORMAT
+#endif
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
new file mode 100644
index 0000000..ae965c5
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
@@ -0,0 +1,228 @@
+/**
+ * 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.
+ */
+
+/**
+ * This file includes some common utilities
+ * for all native code used in chimera.
+ */
+
+#if !defined ORG_APACHE_COMMONS_CRYPTO_H
+#define ORG_APACHE_COMMONS_CRYPTO_H
+
+#if defined(_WIN32)
+#undef UNIX
+#define WINDOWS
+#else
+#undef WINDOWS
+#define UNIX
+#endif
+
+/* A helper macro to 'throw' a java exception. */
+#define THROW(env, exception_name, message) \
+ { \
+ jclass ecls = (*env)->FindClass(env, exception_name); \
+ if (ecls) { \
+ (*env)->ThrowNew(env, ecls, message); \
+ (*env)->DeleteLocalRef(env, ecls); \
+ } \
+ }
+
+/* Helper macro to return if an exception is pending */
+#define PASS_EXCEPTIONS(env) \
+ { \
+ if ((*env)->ExceptionCheck(env)) return; \
+ }
+
+#define PASS_EXCEPTIONS_GOTO(env, target) \
+ { \
+ if ((*env)->ExceptionCheck(env)) goto target; \
+ }
+
+#define PASS_EXCEPTIONS_RET(env, ret) \
+ { \
+ if ((*env)->ExceptionCheck(env)) return (ret); \
+ }
+
+/**
+ * Unix definitions
+ */
+#ifdef UNIX
+#include <config.h>
+#include <dlfcn.h>
+#include <jni.h>
+
+/**
+ * A helper function to dlsym a 'symbol' from a given library-handle.
+ *
+ * @param env jni handle to report contingencies.
+ * @param handle handle to the dlopen'ed library.
+ * @param symbol symbol to load.
+ * @return returns the address where the symbol is loaded in memory,
+ * <code>NULL</code> on error.
+ */
+static __attribute__ ((unused))
+void *do_dlsym(JNIEnv *env, void *handle, const char *symbol) {
+ if (!env || !handle || !symbol) {
+ THROW(env, "java/lang/InternalError", NULL);
+ return NULL;
+ }
+ char *error = NULL;
+ void *func_ptr = dlsym(handle, symbol);
+ if ((error = dlerror()) != NULL) {
+ THROW(env, "java/lang/UnsatisfiedLinkError", symbol);
+ return NULL;
+ }
+ return func_ptr;
+}
+
+/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
+#define LOAD_DYNAMIC_SYMBOL(func_ptr, env, handle, symbol) \
+ if ((func_ptr = do_dlsym(env, handle, symbol)) == NULL) { \
+ return; \
+ }
+#endif
+// Unix part end
+
+
+/**
+ * Windows definitions
+ */
+#ifdef WINDOWS
+
+/* Force using Unicode throughout the code */
+#ifndef UNICODE
+#define UNICODE
+#endif
+
+/* Microsoft C Compiler does not support the C99 inline keyword */
+#ifndef __cplusplus
+#define inline __inline;
+#endif // _cplusplus
+
+/* Optimization macros supported by GCC but for which there is no
+ direct equivalent in the Microsoft C compiler */
+#define likely(_c) (_c)
+#define unlikely(_c) (_c)
+
+/* Disable certain warnings in the native CRC32 code. */
+#pragma warning(disable:4018) // Signed/unsigned mismatch.
+#pragma warning(disable:4244) // Possible loss of data in conversion.
+#pragma warning(disable:4267) // Possible loss of data.
+#pragma warning(disable:4996) // Use of deprecated function.
+
+#include <Windows.h>
+#include <stdio.h>
+#include <jni.h>
+
+#define snprintf(a, b ,c, d) _snprintf_s((a), (b), _TRUNCATE, (c), (d))
+
+/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
+#define LOAD_DYNAMIC_SYMBOL(func_type, func_ptr, env, handle, symbol) \
+ if ((func_ptr = (func_type) do_dlsym(env, handle, symbol)) == NULL) { \
+ return; \
+ }
+
+/**
+ * A helper function to dynamic load a 'symbol' from a given library-handle.
+ *
+ * @param env jni handle to report contingencies.
+ * @param handle handle to the dynamic library.
+ * @param symbol symbol to load.
+ * @return returns the address where the symbol is loaded in memory,
+ * <code>NULL</code> on error.
+ */
+static FARPROC WINAPI do_dlsym(JNIEnv *env, HMODULE handle, LPCSTR symbol) {
+ DWORD dwErrorCode = ERROR_SUCCESS;
+ FARPROC func_ptr = NULL;
+
+ if (!env || !handle || !symbol) {
+ THROW(env, "java/lang/InternalError", NULL);
+ return NULL;
+ }
+
+ func_ptr = GetProcAddress(handle, symbol);
+ if (func_ptr == NULL)
+ {
+ THROW(env, "java/lang/UnsatisfiedLinkError", symbol);
+ }
+ return func_ptr;
+}
+#endif
+// Windows part end
+
+
+#define LOCK_CLASS(env, clazz, classname) \
+ if ((*env)->MonitorEnter(env, clazz) != 0) { \
+ char exception_msg[128]; \
+ snprintf(exception_msg, 128, "Failed to lock %s", classname); \
+ THROW(env, "java/lang/InternalError", exception_msg); \
+ }
+
+#define UNLOCK_CLASS(env, clazz, classname) \
+ if ((*env)->MonitorExit(env, clazz) != 0) { \
+ char exception_msg[128]; \
+ snprintf(exception_msg, 128, "Failed to unlock %s", classname); \
+ THROW(env, "java/lang/InternalError", exception_msg); \
+ }
+
+#define RETRY_ON_EINTR(ret, expr) do { \
+ ret = expr; \
+} while ((ret == -1) && (errno == EINTR));
+
+#ifdef UNIX
+#include <dlfcn.h>
+#include "config.h"
+#endif
+
+#ifdef WINDOWS
+#include "winutils.h"
+#endif
+
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+/**
+ * A helper macro to convert the java 'context-handle'
+ * to a EVP_CIPHER_CTX pointer.
+ */
+#define CONTEXT(context) ((EVP_CIPHER_CTX*)((ptrdiff_t)(context)))
+
+/**
+ * A helper macro to convert the EVP_CIPHER_CTX pointer to the
+ * java 'context-handle'.
+ */
+#define JLONG(context) ((jlong)((ptrdiff_t)(context)))
+
+#define KEY_LENGTH_128 16
+#define KEY_LENGTH_192 24
+#define KEY_LENGTH_256 32
+#define IV_LENGTH 16
+
+#define ENCRYPT_MODE 1
+#define DECRYPT_MODE 0
+
+/** Currently only support AES/CTR/NoPadding. */
+#define AES_CTR 0
+#define AES_CBC 1
+#define NOPADDING 0
+#define PKCS5PADDING 1
+
+#endif
+
+//vim: sw=2: ts=2: et
[7/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
Posted by xu...@apache.org.
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/random/OsSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/random/OsSecureRandom.java b/src/main/java/com/intel/chimera/random/OsSecureRandom.java
deleted file mode 100644
index b174e9f..0000000
--- a/src/main/java/com/intel/chimera/random/OsSecureRandom.java
+++ /dev/null
@@ -1,133 +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 com.intel.chimera.random;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Properties;
-import java.util.Random;
-
-import com.intel.chimera.utils.IOUtils;
-import com.intel.chimera.utils.Utils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A Random implementation that uses random bytes sourced from the
- * operating system.
- */
-public class OsSecureRandom extends Random implements SecureRandom {
- public static final Log LOG = LogFactory.getLog(OsSecureRandom.class);
-
- private static final long serialVersionUID = 6391500337172057900L;
-
- private final int RESERVOIR_LENGTH = 8192;
-
- private String randomDevPath;
-
- private transient FileInputStream stream;
-
- private final byte[] reservoir = new byte[RESERVOIR_LENGTH];
-
- private int pos = reservoir.length;
-
- private void fillReservoir(int min) {
- if (pos >= reservoir.length - min) {
- try {
- IOUtils.readFully(stream, reservoir, 0, reservoir.length);
- } catch (IOException e) {
- throw new RuntimeException("failed to fill reservoir", e);
- }
- pos = 0;
- }
- }
-
- /**
- * Constructs a {@link com.intel.chimera.random.OsSecureRandom}.
- *
- * @param props the configuration properties.
- */
- public OsSecureRandom(Properties props) {
- randomDevPath = Utils.getRandomDevPath(props);
- File randomDevFile = new File(randomDevPath);
-
- try {
- close();
- this.stream = new FileInputStream(randomDevFile);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
-
- try {
- fillReservoir(0);
- } catch (RuntimeException e) {
- close();
- throw e;
- }
- }
-
- /**
- * Overrides {@link com.intel.chimera.random.SecureRandom#nextBytes(byte[])}.
- * Generates random bytes and places them into a user-supplied byte array.
- * The number of random bytes produced is equal to the length of the byte array.
- *
- * @param bytes the array to be filled in with random bytes.
- */
- @Override
- synchronized public void nextBytes(byte[] bytes) {
- int off = 0;
- int n = 0;
- while (off < bytes.length) {
- fillReservoir(0);
- n = Math.min(bytes.length - off, reservoir.length - pos);
- System.arraycopy(reservoir, pos, bytes, off, n);
- off += n;
- pos += n;
- }
- }
-
- /**
- * Overrides {@link java.util.Random# next()}. Generates the next pseudorandom number.
- * Subclasses should override this, as this is used by all other methods.
- *
- * @param nbits random bits.
- * @return the next pseudorandom value from this random number
- * generator's sequence.
- */
- @Override
- synchronized protected int next(int nbits) {
- fillReservoir(4);
- int n = 0;
- for (int i = 0; i < 4; i++) {
- n = ((n << 8) | (reservoir[pos++] & 0xff));
- }
- return n & (0xffffffff >> (32 - nbits));
- }
-
- /**
- * Overrides {@link java.lang.AutoCloseable#close()}. Closes the OS stream.
- */
- @Override
- synchronized public void close() {
- if (stream != null) {
- IOUtils.cleanup(LOG, stream);
- stream = null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/random/SecureRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/random/SecureRandom.java b/src/main/java/com/intel/chimera/random/SecureRandom.java
deleted file mode 100644
index 57b6573..0000000
--- a/src/main/java/com/intel/chimera/random/SecureRandom.java
+++ /dev/null
@@ -1,36 +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 com.intel.chimera.random;
-
-import java.io.Closeable;
-
-/**
- * The interface for SecureRandom.
- */
-public interface SecureRandom extends Closeable {
-
- /**
- * Generates random bytes and places them into a user-supplied
- * byte array. The number of random bytes produced is equal to
- * the length of the byte array.
- *
- * @param bytes the byte array to fill with random bytes
- */
- void nextBytes(byte[] bytes);
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/random/SecureRandomFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/random/SecureRandomFactory.java b/src/main/java/com/intel/chimera/random/SecureRandomFactory.java
deleted file mode 100644
index 58f06f0..0000000
--- a/src/main/java/com/intel/chimera/random/SecureRandomFactory.java
+++ /dev/null
@@ -1,72 +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 com.intel.chimera.random;
-
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.intel.chimera.utils.Utils;
-import com.intel.chimera.utils.ReflectionUtils;
-
-import static com.intel.chimera.conf.ConfigurationKeys
- .CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY;
-
-/**
- * This is the factory class used for {@link SecureRandom}.
- */
-public class SecureRandomFactory {
- public final static Logger LOG = LoggerFactory
- .getLogger(SecureRandomFactory.class);
-
- /**
- * Gets a SecureRandom instance for specified props.
- *
- * @param props the configuration properties.
- * @return SecureRandom the secureRandom object.Null value will be returned if no
- * SecureRandom classes with props.
- */
- public static SecureRandom getSecureRandom(Properties props) {
- String secureRandomClasses = props.getProperty(
- CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY);
- if (secureRandomClasses == null) {
- secureRandomClasses = System.getProperty(
- CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY);
- }
-
- SecureRandom random = null;
- if (secureRandomClasses != null) {
- for (String klassName : Utils.splitClassNames(secureRandomClasses, ",")) {
- try {
- final Class<?> klass = ReflectionUtils.getClassByName(klassName);
- random = (SecureRandom) ReflectionUtils.newInstance(klass, props);
- if (random != null) {
- break;
- }
- } catch (ClassCastException e) {
- LOG.error("Class {} is not a Cipher.", klassName);
- } catch (ClassNotFoundException e) {
- LOG.error("Cipher {} not found.", klassName);
- }
- }
- }
-
- return (random == null) ? new JavaSecureRandom(props) : random;
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/random/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/random/package-info.java b/src/main/java/com/intel/chimera/random/package-info.java
deleted file mode 100644
index 1f71594..0000000
--- a/src/main/java/com/intel/chimera/random/package-info.java
+++ /dev/null
@@ -1,21 +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.
- */
-/**
- * Random classes
- */
-package com.intel.chimera.random;
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/CTRCryptoInputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/CTRCryptoInputStream.java b/src/main/java/com/intel/chimera/stream/CTRCryptoInputStream.java
deleted file mode 100644
index 5f9ce7a..0000000
--- a/src/main/java/com/intel/chimera/stream/CTRCryptoInputStream.java
+++ /dev/null
@@ -1,423 +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 com.intel.chimera.stream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherTransformation;
-import com.intel.chimera.stream.input.ChannelInput;
-import com.intel.chimera.stream.input.Input;
-import com.intel.chimera.stream.input.StreamInput;
-import com.intel.chimera.utils.Utils;
-
-/**
- * CTRCryptoInputStream decrypts data. AES CTR mode is required in order to
- * ensure that the plain text and cipher text have a 1:1 mapping. CTR crypto
- * stream has stream characteristic which is useful for implement features
- * like random seek. The decryption is buffer based. The key points of the
- * decryption are (1) calculating the counter and (2) padding through stream
- * position:
- * <p/>
- * counter = base + pos/(algorithm blocksize);
- * padding = pos%(algorithm blocksize);
- * <p/>
- * The underlying stream offset is maintained as state. It is not thread-safe.
- */
-public class CTRCryptoInputStream extends CryptoInputStream {
- /**
- * Underlying stream offset
- */
- protected long streamOffset = 0;
-
- /**
- * Padding = pos%(algorithm blocksize); Padding is put into {@link #inBuffer}
- * before any other data goes in. The purpose of padding is to put the input
- * data at proper position.
- */
- private byte padding;
-
- /**
- * Flag to mark whether the cipher has been reset
- */
- private boolean cipherReset = false;
-
- public CTRCryptoInputStream(Properties props, InputStream in,
- byte[] key, byte[] iv)
- throws IOException {
- this(props, in, key, iv, 0);
- }
-
- public CTRCryptoInputStream(Properties props, ReadableByteChannel in,
- byte[] key, byte[] iv)
- throws IOException {
- this(props, in, key, iv, 0);
- }
-
- public CTRCryptoInputStream(InputStream in, Cipher cipher, int bufferSize,
- byte[] key, byte[] iv) throws IOException {
- this(in, cipher, bufferSize, key, iv, 0);
- }
-
- public CTRCryptoInputStream(ReadableByteChannel in, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv) throws IOException {
- this(in, cipher, bufferSize, key, iv, 0);
- }
-
- public CTRCryptoInputStream(
- Input input,
- Cipher cipher,
- int bufferSize,
- byte[] key,
- byte[] iv) throws IOException {
- this(input, cipher, bufferSize, key, iv, 0);
- }
-
- public CTRCryptoInputStream(Properties props, InputStream in,
- byte[] key, byte[] iv, long streamOffset)
- throws IOException {
- this(in, Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, props),
- Utils.getBufferSize(props), key, iv, streamOffset);
- }
-
- public CTRCryptoInputStream(Properties props, ReadableByteChannel in,
- byte[] key, byte[] iv, long streamOffset)
- throws IOException {
- this(in, Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, props),
- Utils.getBufferSize(props), key, iv, streamOffset);
- }
-
- public CTRCryptoInputStream(InputStream in, Cipher cipher, int bufferSize,
- byte[] key, byte[] iv, long streamOffset) throws IOException {
- this(new StreamInput(in, bufferSize), cipher, bufferSize, key, iv, streamOffset);
- }
-
- public CTRCryptoInputStream(ReadableByteChannel in, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv, long streamOffset) throws IOException {
- this(new ChannelInput(in), cipher, bufferSize, key, iv, streamOffset);
- }
-
- public CTRCryptoInputStream(
- Input input,
- Cipher cipher,
- int bufferSize,
- byte[] key,
- byte[] iv,
- long streamOffset) throws IOException {
- super(input, cipher, bufferSize, key, iv);
-
- Utils.checkStreamCipher(cipher);
-
- resetStreamOffset(streamOffset);
- }
-
- /** Skip n bytes */
- @Override
- public long skip(long n) throws IOException {
- Utils.checkArgument(n >= 0, "Negative skip length.");
- checkStream();
-
- if (n == 0) {
- return 0;
- } else if (n <= outBuffer.remaining()) {
- int pos = outBuffer.position() + (int) n;
- outBuffer.position(pos);
- return n;
- } else {
- /*
- * Subtract outBuffer.remaining() to see how many bytes we need to
- * skip in the underlying stream. Add outBuffer.remaining() to the
- * actual number of skipped bytes in the underlying stream to get the
- * number of skipped bytes from the user's point of view.
- */
- n -= outBuffer.remaining();
- long skipped = input.skip(n);
- if (skipped < 0) {
- skipped = 0;
- }
- long pos = streamOffset + skipped;
- skipped += outBuffer.remaining();
- resetStreamOffset(pos);
- return skipped;
- }
- }
-
- /** ByteBuffer read. */
- @Override
- public int read(ByteBuffer buf) throws IOException {
- checkStream();
- int unread = outBuffer.remaining();
- if (unread <= 0) { // Fill the unread decrypted data buffer firstly
- final int n = input.read(inBuffer);
- if (n <= 0) {
- return n;
- }
-
- streamOffset += n; // Read n bytes
- if (buf.isDirect() && buf.remaining() >= inBuffer.position() && padding == 0) {
- // Use buf as the output buffer directly
- decryptInPlace(buf);
- padding = postDecryption(streamOffset);
- return n;
- } else {
- // Use outBuffer as the output buffer
- decrypt();
- padding = postDecryption(streamOffset);
- }
- }
-
- // Copy decrypted data from outBuffer to buf
- unread = outBuffer.remaining();
- final int toRead = buf.remaining();
- if (toRead <= unread) {
- final int limit = outBuffer.limit();
- outBuffer.limit(outBuffer.position() + toRead);
- buf.put(outBuffer);
- outBuffer.limit(limit);
- return toRead;
- } else {
- buf.put(outBuffer);
- return unread;
- }
- }
-
- /**
- * Seek the stream to a specific position relative to start of the under layer stream.
- *
- * @param position The position to seek to
- * @throws IOException if seek failed
- */
- public void seek(long position) throws IOException {
- Utils.checkArgument(position >= 0, "Cannot seek to negative offset.");
- checkStream();
- /*
- * If data of target pos in the underlying stream has already been read
- * and decrypted in outBuffer, we just need to re-position outBuffer.
- */
- if (position >= getStreamPosition() && position <= getStreamOffset()) {
- int forward = (int) (position - getStreamPosition());
- if (forward > 0) {
- outBuffer.position(outBuffer.position() + forward);
- }
- } else {
- input.seek(position);
- resetStreamOffset(position);
- }
- }
-
- protected long getStreamOffset() {
- return streamOffset;
- }
-
- protected long getStreamPosition() {
- return streamOffset - outBuffer.remaining();
- }
-
- /**
- * Decrypt more data by reading the under layer stream. The decrypted data will
- * be put in the output buffer.
- *
- * @return The number of decrypted data. -1 if end of the decrypted stream
- */
- protected int decryptMore() throws IOException {
- int n = input.read(inBuffer);
- if (n <= 0) {
- return n;
- }
-
- streamOffset += n; // Read n bytes
- decrypt();
- padding = postDecryption(streamOffset);
- return outBuffer.remaining();
- }
-
- /**
- * Do the decryption using inBuffer as input and outBuffer as output.
- * Upon return, inBuffer is cleared; the decrypted data starts at
- * outBuffer.position() and ends at outBuffer.limit();
- */
- protected void decrypt() throws IOException {
- Utils.checkState(inBuffer.position() >= padding);
- if(inBuffer.position() == padding) {
- // There is no real data in inBuffer.
- return;
- }
-
- inBuffer.flip();
- outBuffer.clear();
- decryptBuffer(outBuffer);
- inBuffer.clear();
- outBuffer.flip();
-
- if (padding > 0) {
- /*
- * The plain text and cipher text have a 1:1 mapping, they start at the
- * same position.
- */
- outBuffer.position(padding);
- }
- }
-
- /**
- * Do the decryption using inBuffer as input and buf as output.
- * Upon return, inBuffer is cleared; the buf's position will be equal to
- * <i>p</i> <tt>+</tt> <i>n</i> where <i>p</i> is the position before
- * decryption, <i>n</i> is the number of bytes decrypted.
- * The buf's limit will not have changed.
- */
- protected void decryptInPlace(ByteBuffer buf) throws IOException {
- Utils.checkState(inBuffer.position() >= padding);
- Utils.checkState(buf.isDirect());
- Utils.checkState(buf.remaining() >= inBuffer.position());
- Utils.checkState(padding == 0);
-
- if(inBuffer.position() == padding) {
- // There is no real data in inBuffer.
- return;
- }
- inBuffer.flip();
- decryptBuffer(buf);
- inBuffer.clear();
- }
-
- /**
- * Decrypt all data in buf: total n bytes from given start position.
- * Output is also buf and same start position.
- * buf.position() and buf.limit() should be unchanged after decryption.
- */
- protected void decrypt(ByteBuffer buf, int offset, int len)
- throws IOException {
- final int pos = buf.position();
- final int limit = buf.limit();
- int n = 0;
- while (n < len) {
- buf.position(offset + n);
- buf.limit(offset + n + Math.min(len - n, inBuffer.remaining()));
- inBuffer.put(buf);
- // Do decryption
- try {
- decrypt();
- buf.position(offset + n);
- buf.limit(limit);
- n += outBuffer.remaining();
- buf.put(outBuffer);
- } finally {
- padding = postDecryption(streamOffset - (len - n));
- }
- }
- buf.position(pos);
- }
-
- /**
- * This method is executed immediately after decryption. Check whether
- * cipher should be updated and recalculate padding if needed.
- */
- protected byte postDecryption(long position) throws IOException {
- byte padding = 0;
- if (cipherReset) {
- /*
- * This code is generally not executed since the cipher usually
- * maintains cipher context (e.g. the counter) internally. However,
- * some implementations can't maintain context so a re-init is necessary
- * after each decryption call.
- */
- resetCipher(position);
- padding = getPadding(position);
- inBuffer.position(padding);
- }
- return padding;
- }
-
- protected long getCounter(long position) {
- return position / cipher.getTransformation().getAlgorithmBlockSize();
- }
-
- protected byte getPadding(long position) {
- return (byte)(position % cipher.getTransformation().getAlgorithmBlockSize());
- }
-
- /** Initialize the cipher. */
- @Override
- protected void initCipher() {
- // Do nothing for initCipher
- // Will reset the cipher when reset the stream offset
- }
-
- /** Calculate the counter and iv, reset the cipher. */
- protected void resetCipher(long position)
- throws IOException {
- final long counter = getCounter(position);
- Utils.calculateIV(initIV, counter, iv);
- try {
- cipher.init(Cipher.DECRYPT_MODE, key, iv);
- } catch (InvalidKeyException e) {
- throw new IOException(e);
- } catch (InvalidAlgorithmParameterException e) {
- throw new IOException(e);
- }
- cipherReset = false;
- }
-
- /**
- * Reset the underlying stream offset; clear {@link #inBuffer} and
- * {@link #outBuffer}. This Typically happens during {@link #skip(long)}.
- */
- protected void resetStreamOffset(long offset) throws IOException {
- streamOffset = offset;
- inBuffer.clear();
- outBuffer.clear();
- outBuffer.limit(0);
- resetCipher(offset);
- padding = getPadding(offset);
- inBuffer.position(padding); // Set proper position for input data.
- }
-
- protected void decryptBuffer(ByteBuffer out)
- throws IOException {
- int inputSize = inBuffer.remaining();
- try {
- int n = cipher.update(inBuffer, out);
- if (n < inputSize) {
- /**
- * Typically code will not get here. Cipher#update will consume all
- * input data and put result in outBuffer.
- * Cipher#doFinal will reset the cipher context.
- */
- cipher.doFinal(inBuffer, out);
- cipherReset = true;
- }
- } catch (ShortBufferException e) {
- throw new IOException(e);
- } catch (IllegalBlockSizeException e) {
- throw new IOException(e);
- } catch (BadPaddingException e) {
- throw new IOException(e);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/CTRCryptoOutputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/CTRCryptoOutputStream.java b/src/main/java/com/intel/chimera/stream/CTRCryptoOutputStream.java
deleted file mode 100644
index 152d4fe..0000000
--- a/src/main/java/com/intel/chimera/stream/CTRCryptoOutputStream.java
+++ /dev/null
@@ -1,230 +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 com.intel.chimera.stream;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.WritableByteChannel;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherTransformation;
-import com.intel.chimera.stream.output.ChannelOutput;
-import com.intel.chimera.stream.output.Output;
-import com.intel.chimera.stream.output.StreamOutput;
-import com.intel.chimera.utils.Utils;
-
-/**
- * CTRCryptoOutputStream encrypts data. It is not thread-safe. AES CTR mode is
- * required in order to ensure that the plain text and cipher text have a 1:1
- * mapping. The encryption is buffer based. The key points of the encryption are
- * (1) calculating counter and (2) padding through stream position.
- * <p/>
- * counter = base + pos/(algorithm blocksize);
- * padding = pos%(algorithm blocksize);
- * <p/>
- * The underlying stream offset is maintained as state.
- */
-public class CTRCryptoOutputStream extends CryptoOutputStream {
- /**
- * Underlying stream offset.
- */
- protected long streamOffset = 0;
-
- /**
- * Padding = pos%(algorithm blocksize); Padding is put into {@link #inBuffer}
- * before any other data goes in. The purpose of padding is to put input data
- * at proper position.
- */
- private byte padding;
-
- /**
- * Flag to mark whether the cipher has been reset
- */
- private boolean cipherReset = false;
-
- public CTRCryptoOutputStream(Properties props, OutputStream out,
- byte[] key, byte[] iv)
- throws IOException {
- this(props, out, key, iv, 0);
- }
-
- public CTRCryptoOutputStream(Properties props, WritableByteChannel out,
- byte[] key, byte[] iv)
- throws IOException {
- this(props, out, key, iv, 0);
- }
-
- public CTRCryptoOutputStream(OutputStream out, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv) throws IOException {
- this(out, cipher, bufferSize, key, iv, 0);
- }
-
- public CTRCryptoOutputStream(WritableByteChannel channel, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv) throws IOException {
- this(channel, cipher, bufferSize, key, iv, 0);
- }
-
- public CTRCryptoOutputStream(Output output, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv)
- throws IOException {
- this(output, cipher, bufferSize, key, iv, 0);
- }
-
- public CTRCryptoOutputStream(Properties props, OutputStream out,
- byte[] key, byte[] iv, long streamOffset)
- throws IOException {
- this(out, Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, props),
- Utils.getBufferSize(props), key, iv, streamOffset);
- }
-
- public CTRCryptoOutputStream(Properties props, WritableByteChannel out,
- byte[] key, byte[] iv, long streamOffset)
- throws IOException {
- this(out, Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, props),
- Utils.getBufferSize(props), key, iv, streamOffset);
- }
-
- public CTRCryptoOutputStream(OutputStream out, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv, long streamOffset) throws IOException {
- this(new StreamOutput(out, bufferSize), cipher,
- bufferSize, key, iv, streamOffset);
- }
-
- public CTRCryptoOutputStream(WritableByteChannel channel, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv, long streamOffset) throws IOException {
- this(new ChannelOutput(channel), cipher,
- bufferSize, key, iv, streamOffset);
- }
-
- public CTRCryptoOutputStream(Output output, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv, long streamOffset)
- throws IOException {
- super(output, cipher, bufferSize, key, iv);
-
- Utils.checkStreamCipher(cipher);
- this.streamOffset = streamOffset;
-
- resetCipher();
- }
-
- /**
- * Do the encryption, input is {@link #inBuffer} and output is
- * {@link #outBuffer}.
- */
- @Override
- protected void encrypt() throws IOException {
- Utils.checkState(inBuffer.position() >= padding);
- if (inBuffer.position() == padding) {
- // There is no real data in the inBuffer.
- return;
- }
-
- inBuffer.flip();
- outBuffer.clear();
- encryptBuffer(outBuffer);
- inBuffer.clear();
- outBuffer.flip();
-
- if (padding > 0) {
- /*
- * The plain text and cipher text have a 1:1 mapping, they start at the
- * same position.
- */
- outBuffer.position(padding);
- padding = 0;
- }
-
- final int len = output.write(outBuffer);
- streamOffset += len;
- if (cipherReset) {
- /*
- * This code is generally not executed since the encryptor usually
- * maintains encryption context (e.g. the counter) internally. However,
- * some implementations can't maintain context so a re-init is necessary
- * after each encryption call.
- */
- resetCipher();
- }
- }
-
- /**
- * Do final encryption of the last data
- */
- @Override
- protected void encryptFinal() throws IOException {
- // The same as the normal encryption for Counter mode
- encrypt();
- }
-
- /** Initialize the cipher. */
- @Override
- protected void initCipher() {
- // Do nothing for initCipher
- // Will reset the cipher considering the stream offset
- }
-
- /** Reset the {@link #cipher}: calculate counter and {@link #padding}. */
- private void resetCipher() throws IOException {
- final long counter =
- streamOffset / cipher.getTransformation().getAlgorithmBlockSize();
- padding =
- (byte)(streamOffset % cipher.getTransformation().getAlgorithmBlockSize());
- inBuffer.position(padding); // Set proper position for input data.
-
- Utils.calculateIV(initIV, counter, iv);
- try {
- cipher.init(Cipher.ENCRYPT_MODE, key, iv);
- } catch (InvalidKeyException e) {
- throw new IOException(e);
- }catch (InvalidAlgorithmParameterException e) {
- throw new IOException(e);
- }
- cipherReset = false;
- }
-
- private void encryptBuffer(ByteBuffer out)
- throws IOException {
- int inputSize = inBuffer.remaining();
- try {
- int n = cipher.update(inBuffer, out);
- if (n < inputSize) {
- /**
- * Typically code will not get here. Cipher#update will consume all
- * input data and put result in outBuffer.
- * Cipher#doFinal will reset the cipher context.
- */
- cipher.doFinal(inBuffer, out);
- cipherReset = true;
- }
- } catch (ShortBufferException e) {
- throw new IOException(e);
- } catch (BadPaddingException e) {
- throw new IOException(e);
- } catch (IllegalBlockSizeException e) {
- throw new IOException(e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/CryptoInputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/CryptoInputStream.java b/src/main/java/com/intel/chimera/stream/CryptoInputStream.java
deleted file mode 100644
index 01bf83f..0000000
--- a/src/main/java/com/intel/chimera/stream/CryptoInputStream.java
+++ /dev/null
@@ -1,394 +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 com.intel.chimera.stream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherTransformation;
-import com.intel.chimera.stream.input.ChannelInput;
-import com.intel.chimera.stream.input.Input;
-import com.intel.chimera.stream.input.StreamInput;
-import com.intel.chimera.utils.Utils;
-
-/**
- * CryptoInputStream reads input data and decrypts data in stream manner. It supports
- * any mode of operations such as AES CBC/CTR/GCM mode in concept.It is not thread-safe.
- *
- */
-
-public class CryptoInputStream extends InputStream implements
- ReadableByteChannel {
- private final byte[] oneByteBuf = new byte[1];
-
- protected final Cipher cipher;
- protected final int bufferSize;
-
- protected final byte[] key;
- protected final byte[] initIV;
- protected byte[] iv;
-
- protected boolean closed;
- protected boolean finalDone = false;
-
- protected Input input;
-
- /**
- * Input data buffer. The data starts at inBuffer.position() and ends at
- * to inBuffer.limit().
- */
- protected ByteBuffer inBuffer;
-
- /**
- * The decrypted data buffer. The data starts at outBuffer.position() and
- * ends at outBuffer.limit();
- */
- protected ByteBuffer outBuffer;
-
- public CryptoInputStream(CipherTransformation transformation,
- Properties props, InputStream in, byte[] key, byte[] iv)
- throws IOException {
- this(in, Utils.getCipherInstance(transformation, props),
- Utils.getBufferSize(props), key, iv);
- }
-
- public CryptoInputStream(CipherTransformation transformation,
- Properties props, ReadableByteChannel in, byte[] key, byte[] iv)
- throws IOException {
- this(in, Utils.getCipherInstance(transformation, props),
- Utils.getBufferSize(props), key, iv);
- }
-
- public CryptoInputStream(InputStream in, Cipher cipher, int bufferSize,
- byte[] key, byte[] iv) throws IOException {
- this(new StreamInput(in, bufferSize), cipher, bufferSize, key, iv);
- }
-
- public CryptoInputStream(ReadableByteChannel in, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv) throws IOException {
- this(new ChannelInput(in), cipher, bufferSize, key, iv);
- }
-
- public CryptoInputStream(
- Input input,
- Cipher cipher,
- int bufferSize,
- byte[] key,
- byte[] iv) throws IOException {
- this.input = input;
- this.cipher = cipher;
- this.bufferSize = Utils.checkBufferSize(cipher, bufferSize);
- this.key = key.clone();
- this.initIV = iv.clone();
- this.iv = iv.clone();
-
- inBuffer = ByteBuffer.allocateDirect(this.bufferSize);
- outBuffer = ByteBuffer.allocateDirect(this.bufferSize +
- cipher.getTransformation().getAlgorithmBlockSize());
- outBuffer.limit(0);
-
- initCipher();
- }
-
- @Override
- public int read() throws IOException {
- int n;
- while ((n = read(oneByteBuf, 0, 1)) == 0) ;
- return (n == -1) ? -1 : oneByteBuf[0] & 0xff;
- }
-
- /**
- * Decryption is buffer based.
- * If there is data in {@link #outBuffer}, then read it out of this buffer.
- * If there is no data in {@link #outBuffer}, then read more from the
- * underlying stream and do the decryption.
- * @param b the buffer into which the decrypted data is read.
- * @param off the buffer offset.
- * @param len the maximum number of decrypted data bytes to read.
- * @return int the total number of decrypted data bytes read into the buffer.
- * @throws IOException
- */
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- checkStream();
- if (b == null) {
- throw new NullPointerException();
- } else if (off < 0 || len < 0 || len > b.length - off) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return 0;
- }
-
- int remaining = outBuffer.remaining();
- if (remaining > 0) {
- // Satisfy the read with the existing data
- int n = Math.min(len, remaining);
- outBuffer.get(b, off, n);
- return n;
- } else {
- // No data in the out buffer, try read new data and decrypt it
- int nd = decryptMore();
- if(nd <= 0)
- return nd;
-
- int n = Math.min(len, outBuffer.remaining());
- outBuffer.get(b, off, n);
- return n;
- }
- }
-
- @Override
- public long skip(long n) throws IOException {
- Utils.checkArgument(n >= 0, "Negative skip length.");
- checkStream();
-
- if (n == 0) {
- return 0;
- }
-
- long remaining = n;
- int nd;
-
- while (remaining > 0) {
- if(remaining <= outBuffer.remaining()) {
- // Skip in the remaining buffer
- int pos = outBuffer.position() + (int) remaining;
- outBuffer.position(pos);
-
- remaining = 0;
- break;
- } else {
- remaining -= outBuffer.remaining();
- outBuffer.clear();
- }
-
- nd = decryptMore();
- if (nd < 0) {
- break;
- }
- }
-
- return n - remaining;
- }
-
- @Override
- public int available() throws IOException {
- checkStream();
-
- return input.available() + outBuffer.remaining();
- }
-
- @Override
- public void close() throws IOException {
- if (closed) {
- return;
- }
-
- input.close();
- freeBuffers();
- cipher.close();
- super.close();
- closed = true;
- }
-
- @Override
- public void mark(int readlimit) {
- }
-
- @Override
- public void reset() throws IOException {
- throw new IOException("Mark/reset not supported");
- }
-
- @Override
- public boolean markSupported() {
- return false;
- }
-
- @Override
- public boolean isOpen() {
- return !closed;
- }
-
- @Override
- public int read(ByteBuffer dst) throws IOException {
- checkStream();
- int remaining = outBuffer.remaining();
- if (remaining <= 0) {
- // Decrypt more data
- int nd = decryptMore();
- if(nd < 0) {
- return -1;
- }
- }
-
- // Copy decrypted data from outBuffer to dst
- remaining = outBuffer.remaining();
- final int toRead = dst.remaining();
- if (toRead <= remaining) {
- final int limit = outBuffer.limit();
- outBuffer.limit(outBuffer.position() + toRead);
- dst.put(outBuffer);
- outBuffer.limit(limit);
- return toRead;
- } else {
- dst.put(outBuffer);
- return remaining;
- }
- }
-
- /**
- * Get the buffer size
- */
- protected int getBufferSize() {
- return bufferSize;
- }
-
- /**
- * Get the key
- */
- protected byte[] getKey() {
- return key;
- }
-
- /**
- * Get the initialization vector
- */
- protected byte[] getInitIV() {
- return initIV;
- }
-
- /**
- * Get the internal Cipher
- */
- protected Cipher getCipher() {
- return cipher;
- }
-
- /** Initialize the cipher. */
- protected void initCipher()
- throws IOException {
- try {
- cipher.init(Cipher.DECRYPT_MODE, key, iv);
- } catch (InvalidKeyException e) {
- throw new IOException(e);
- } catch(InvalidAlgorithmParameterException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Decrypt more data by reading the under layer stream. The decrypted data will
- * be put in the output buffer. If the end of the under stream reached, we will
- * do final of the cipher to finish all the decrypting of data.
- *
- * @return The number of decrypted data. -1 if end of the decrypted stream
- */
- protected int decryptMore() throws IOException {
- if(finalDone) {
- return -1;
- }
-
- int n = input.read(inBuffer);
- if (n < 0) {
- // The stream is end, finalize the cipher stream
- decryptFinal();
-
- // Satisfy the read with the remaining
- int remaining = outBuffer.remaining();
- if (remaining > 0) {
- return remaining;
- }
-
- // End of the stream
- return -1;
- } else if(n == 0) {
- // No data is read, but the stream is not end yet
- return 0;
- } else {
- decrypt();
- return outBuffer.remaining();
- }
- }
-
- /**
- * Do the decryption using inBuffer as input and outBuffer as output.
- * Upon return, inBuffer is cleared; the decrypted data starts at
- * outBuffer.position() and ends at outBuffer.limit();
- */
- protected void decrypt() throws IOException {
- // Prepare the input buffer and clear the out buffer
- inBuffer.flip();
- outBuffer.clear();
-
- try {
- cipher.update(inBuffer, outBuffer);
- } catch (ShortBufferException e) {
- throw new IOException(e);
- }
-
- // Clear the input buffer and prepare out buffer
- inBuffer.clear();
- outBuffer.flip();
- }
-
- /**
- * Do final of the cipher to end the decrypting stream
- */
- protected void decryptFinal() throws IOException {
- // Prepare the input buffer and clear the out buffer
- inBuffer.flip();
- outBuffer.clear();
-
- try {
- cipher.doFinal(inBuffer, outBuffer);
- finalDone = true;
- } catch (ShortBufferException e) {
- throw new IOException(e);
- } catch (IllegalBlockSizeException e) {
- throw new IOException(e);
- } catch( BadPaddingException e) {
- throw new IOException(e);
- }
-
- // Clear the input buffer and prepare out buffer
- inBuffer.clear();
- outBuffer.flip();
- }
-
- protected void checkStream() throws IOException {
- if (closed) {
- throw new IOException("Stream closed");
- }
- }
-
- /** Forcibly free the direct buffers. */
- protected void freeBuffers() {
- Utils.freeDirectBuffer(inBuffer);
- Utils.freeDirectBuffer(outBuffer);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/CryptoOutputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/CryptoOutputStream.java b/src/main/java/com/intel/chimera/stream/CryptoOutputStream.java
deleted file mode 100644
index f9cb4ed..0000000
--- a/src/main/java/com/intel/chimera/stream/CryptoOutputStream.java
+++ /dev/null
@@ -1,283 +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 com.intel.chimera.stream;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.WritableByteChannel;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherTransformation;
-import com.intel.chimera.stream.output.ChannelOutput;
-import com.intel.chimera.stream.output.Output;
-import com.intel.chimera.stream.output.StreamOutput;
-import com.intel.chimera.utils.Utils;
-
-/**
- * CryptoOutputStream encrypts data and writes to the under layer output. It supports
- * any mode of operations such as AES CBC/CTR/GCM mode in concept. It is not thread-safe.
- */
-
-public class CryptoOutputStream extends OutputStream implements
- WritableByteChannel {
- private final byte[] oneByteBuf = new byte[1];
-
- protected Output output;
- protected final Cipher cipher;
- protected final int bufferSize;
-
- protected final byte[] key;
- protected final byte[] initIV;
- protected byte[] iv;
-
- protected boolean closed;
-
- /**
- * Input data buffer. The data starts at inBuffer.position() and ends at
- * inBuffer.limit().
- */
- protected ByteBuffer inBuffer;
-
- /**
- * Encrypted data buffer. The data starts at outBuffer.position() and ends at
- * outBuffer.limit();
- */
- protected ByteBuffer outBuffer;
-
- public CryptoOutputStream(CipherTransformation transformation,
- Properties props, OutputStream out, byte[] key, byte[] iv)
- throws IOException {
- this(out, Utils.getCipherInstance(transformation, props),
- Utils.getBufferSize(props), key, iv);
- }
-
- public CryptoOutputStream(CipherTransformation transformation,
- Properties props, WritableByteChannel out, byte[] key, byte[] iv)
- throws IOException {
- this(out, Utils.getCipherInstance(transformation, props),
- Utils.getBufferSize(props), key, iv);
- }
-
- public CryptoOutputStream(OutputStream out, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv) throws IOException {
- this(new StreamOutput(out, bufferSize), cipher, bufferSize, key, iv);
- }
-
- public CryptoOutputStream(WritableByteChannel channel, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv) throws IOException {
- this(new ChannelOutput(channel), cipher, bufferSize, key, iv);
- }
-
- protected CryptoOutputStream(Output output, Cipher cipher,
- int bufferSize, byte[] key, byte[] iv)
- throws IOException {
-
- this.output = output;
- this.bufferSize = Utils.checkBufferSize(cipher, bufferSize);
- this.cipher = cipher;
- this.key = key.clone();
- this.initIV = iv.clone();
- this.iv = iv.clone();
- inBuffer = ByteBuffer.allocateDirect(this.bufferSize);
- outBuffer = ByteBuffer.allocateDirect(this.bufferSize +
- cipher.getTransformation().getAlgorithmBlockSize());
-
- initCipher();
- }
-
- @Override
- public void write(int b) throws IOException {
- oneByteBuf[0] = (byte)(b & 0xff);
- write(oneByteBuf, 0, oneByteBuf.length);
- }
-
- /**
- * Encryption is buffer based.
- * If there is enough room in {@link #inBuffer}, then write to this buffer.
- * If {@link #inBuffer} is full, then do encryption and write data to the
- * underlying stream.
- * @param b the data.
- * @param off the start offset in the data.
- * @param len the number of bytes to write.
- * @throws IOException
- */
- public void write(byte[] b, int off, int len) throws IOException {
- checkStream();
- if (b == null) {
- throw new NullPointerException();
- } else if (off < 0 || len < 0 || off > b.length ||
- len > b.length - off) {
- throw new IndexOutOfBoundsException();
- }
-
- while (len > 0) {
- final int remaining = inBuffer.remaining();
- if (len < remaining) {
- inBuffer.put(b, off, len);
- len = 0;
- } else {
- inBuffer.put(b, off, remaining);
- off += remaining;
- len -= remaining;
- encrypt();
- }
- }
- }
-
- /**
- * To flush, we need to encrypt the data in the buffer and write to the
- * underlying stream, then do the flush.
- */
- @Override
- public void flush() throws IOException {
- checkStream();
- encrypt();
- output.flush();
- super.flush();
- }
-
- @Override
- public void close() throws IOException {
- if (closed) {
- return;
- }
-
- try {
- encryptFinal();
- output.close();
- freeBuffers();
- cipher.close();
- super.close();
- } finally {
- closed = true;
- }
- }
-
- @Override
- public boolean isOpen() {
- return !closed;
- }
-
- @Override
- public int write(ByteBuffer src) throws IOException {
- checkStream();
- final int len = src.remaining();
- int remaining = len;
- while (remaining > 0) {
- final int space = inBuffer.remaining();
- if (remaining < space) {
- inBuffer.put(src);
- remaining = 0;
- } else {
- // to void copy twice, we set the limit to copy directly
- final int oldLimit = src.limit();
- final int newLimit = src.position() + space;
- src.limit(newLimit);
-
- inBuffer.put(src);
-
- // restore the old limit
- src.limit(oldLimit);
-
- remaining -= space;
- encrypt();
- }
- }
-
- return len;
- }
-
- /** Initialize the cipher. */
- protected void initCipher()
- throws IOException {
- try {
- cipher.init(Cipher.ENCRYPT_MODE, key, iv);
- } catch (InvalidKeyException e) {
- throw new IOException(e);
- } catch(InvalidAlgorithmParameterException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Do the encryption, input is {@link #inBuffer} and output is
- * {@link #outBuffer}.
- */
- protected void encrypt() throws IOException {
-
- inBuffer.flip();
- outBuffer.clear();
-
- try {
- cipher.update(inBuffer, outBuffer);
- } catch (ShortBufferException e) {
- throw new IOException(e);
- }
-
- inBuffer.clear();
- outBuffer.flip();
-
- // write to output
- output.write(outBuffer);
- }
-
- /**
- * Do final encryption of the last data
- */
- protected void encryptFinal() throws IOException {
- inBuffer.flip();
- outBuffer.clear();
-
- try {
- cipher.doFinal(inBuffer, outBuffer);
- } catch (ShortBufferException e) {
- throw new IOException(e);
- } catch (IllegalBlockSizeException e) {
- throw new IOException(e);
- } catch( BadPaddingException e) {
- throw new IOException(e);
- }
-
- inBuffer.clear();
- outBuffer.flip();
-
- // write to output
- output.write(outBuffer);
- }
-
- protected void checkStream() throws IOException {
- if (closed) {
- throw new IOException("Stream closed");
- }
- }
-
- /** Forcibly free the direct buffers. */
- protected void freeBuffers() {
- Utils.freeDirectBuffer(inBuffer);
- Utils.freeDirectBuffer(outBuffer);
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/PositionedCryptoInputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/PositionedCryptoInputStream.java b/src/main/java/com/intel/chimera/stream/PositionedCryptoInputStream.java
deleted file mode 100644
index d9686f3..0000000
--- a/src/main/java/com/intel/chimera/stream/PositionedCryptoInputStream.java
+++ /dev/null
@@ -1,311 +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 com.intel.chimera.stream;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherFactory;
-import com.intel.chimera.stream.input.Input;
-import com.intel.chimera.utils.IOUtils;
-import com.intel.chimera.utils.Utils;
-
-import static com.intel.chimera.cipher.CipherTransformation.AES_CTR_NOPADDING;
-
-/**
- * PositionedCryptoInputStream provides the capability to decrypt the stream starting
- * at random position as well as provides the foundation for positioned read for
- * decrypting. This needs a stream cipher mode such as AES CTR mode.
- */
-public class PositionedCryptoInputStream extends CTRCryptoInputStream {
-
- /**
- * DirectBuffer pool
- */
- private final Queue<ByteBuffer> bufferPool = new
- ConcurrentLinkedQueue<ByteBuffer>();
-
- /**
- * Cipher pool
- */
- private final Queue<CipherState> cipherPool = new
- ConcurrentLinkedQueue<CipherState>();
-
- public PositionedCryptoInputStream(Properties props, Input in,
- byte[] key, byte[] iv, long streamOffset) throws IOException {
- this(in, Utils.getCipherInstance(AES_CTR_NOPADDING, props),
- Utils.getBufferSize(props), key, iv, streamOffset);
- }
-
- public PositionedCryptoInputStream(
- Input input,
- Cipher cipher,
- int bufferSize,
- byte[] key,
- byte[] iv,
- long streamOffset) throws IOException {
- super(input, cipher, bufferSize, key, iv, streamOffset);
- }
-
- /**
- * Read upto the specified number of bytes from a given position
- * within a stream and return the number of bytes read. This does not
- * change the current offset of the stream, and is thread-safe.
- */
- public int read(long position, byte[] buffer, int offset, int length)
- throws IOException {
- checkStream();
- final int n = input.read(position, buffer, offset, length);
- if (n > 0) {
- // This operation does not change the current offset of the file
- decrypt(position, buffer, offset, n);
- }
- return n;
- }
-
- /**
- * Read the specified number of bytes from a given position within a stream.
- * This does not change the current offset of the stream and is thread-safe.
- */
- public void readFully(long position, byte[] buffer, int offset, int length)
- throws IOException {
- checkStream();
- IOUtils.readFully(input, position, buffer, offset, length);
- if (length > 0) {
- // This operation does not change the current offset of the file
- decrypt(position, buffer, offset, length);
- }
- }
-
- public void readFully(long position, byte[] buffer) throws IOException {
- readFully(position, buffer, 0, buffer.length);
- }
-
- /**
- * Decrypt length bytes in buffer starting at offset. Output is also put
- * into buffer starting at offset. It is thread-safe.
- */
- protected void decrypt(long position, byte[] buffer, int offset, int length)
- throws IOException {
- ByteBuffer inBuffer = getBuffer();
- ByteBuffer outBuffer = getBuffer();
- CipherState state = null;
- try {
- state = getCipherState();
- byte[] iv = getInitIV().clone();
- resetCipher(state, position, iv);
- byte padding = getPadding(position);
- inBuffer.position(padding); // Set proper position for input data.
-
- int n = 0;
- while (n < length) {
- int toDecrypt = Math.min(length - n, inBuffer.remaining());
- inBuffer.put(buffer, offset + n, toDecrypt);
-
- // Do decryption
- decrypt(state, inBuffer, outBuffer, padding);
-
- outBuffer.get(buffer, offset + n, toDecrypt);
- n += toDecrypt;
- padding = postDecryption(state, inBuffer, position + n, iv);
- }
- } finally {
- returnBuffer(inBuffer);
- returnBuffer(outBuffer);
- returnCipherState(state);
- }
- }
-
- /**
- * Do the decryption using inBuffer as input and outBuffer as output.
- * Upon return, inBuffer is cleared; the decrypted data starts at
- * outBuffer.position() and ends at outBuffer.limit();
- */
- private void decrypt(CipherState state, ByteBuffer inBuffer,
- ByteBuffer outBuffer, byte padding) throws IOException {
- Utils.checkState(inBuffer.position() >= padding);
- if(inBuffer.position() == padding) {
- // There is no real data in inBuffer.
- return;
- }
- inBuffer.flip();
- outBuffer.clear();
- decryptBuffer(state, inBuffer, outBuffer);
- inBuffer.clear();
- outBuffer.flip();
- if (padding > 0) {
- /*
- * The plain text and cipher text have a 1:1 mapping, they start at the
- * same position.
- */
- outBuffer.position(padding);
- }
- }
-
- private void decryptBuffer(CipherState state, ByteBuffer inBuffer, ByteBuffer outBuffer)
- throws IOException {
- int inputSize = inBuffer.remaining();
- try {
- int n = state.getCipher().update(inBuffer, outBuffer);
- if (n < inputSize) {
- /**
- * Typically code will not get here. Cipher#update will consume all
- * input data and put result in outBuffer.
- * Cipher#doFinal will reset the cipher context.
- */
- state.getCipher().doFinal(inBuffer, outBuffer);
- state.reset(true);
- }
- } catch (ShortBufferException e) {
- throw new IOException(e);
- } catch (IllegalBlockSizeException e) {
- throw new IOException(e);
- } catch (BadPaddingException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * This method is executed immediately after decryption. Check whether
- * cipher should be updated and recalculate padding if needed.
- */
- private byte postDecryption(CipherState state, ByteBuffer inBuffer,
- long position, byte[] iv) throws IOException {
- byte padding = 0;
- if (state.isReset()) {
- /*
- * This code is generally not executed since the cipher usually
- * maintains cipher context (e.g. the counter) internally. However,
- * some implementations can't maintain context so a re-init is necessary
- * after each decryption call.
- */
- resetCipher(state, position, iv);
- padding = getPadding(position);
- inBuffer.position(padding);
- }
- return padding;
- }
-
- /** Calculate the counter and iv, reset the cipher. */
- private void resetCipher(CipherState state, long position, byte[] iv)
- throws IOException {
- final long counter = getCounter(position);
- Utils.calculateIV(getInitIV(), counter, iv);
- try {
- state.getCipher().init(Cipher.DECRYPT_MODE, getKey(), iv);
- } catch (InvalidKeyException e) {
- throw new IOException(e);
- } catch (InvalidAlgorithmParameterException e) {
- throw new IOException(e);
- }
- state.reset(false);
- }
-
- /** Get Cipher from pool */
- private CipherState getCipherState() throws IOException {
- CipherState state = cipherPool.poll();
- if (state == null) {
- Cipher cipher;
- try {
- cipher = CipherFactory.getInstance(getCipher().getTransformation(),
- getCipher().getProperties());
- } catch (GeneralSecurityException e) {
- throw new IOException(e);
- }
- state = new CipherState(cipher);
- }
-
- return state;
- }
-
- /** Return Cipher to pool */
- private void returnCipherState(CipherState state) {
- if (state != null) {
- cipherPool.add(state);
- }
- }
-
- /** Get direct buffer from pool */
- private ByteBuffer getBuffer() {
- ByteBuffer buffer = bufferPool.poll();
- if (buffer == null) {
- buffer = ByteBuffer.allocateDirect(getBufferSize());
- }
-
- return buffer;
- }
-
- /** Return direct buffer to pool */
- private void returnBuffer(ByteBuffer buf) {
- if (buf != null) {
- buf.clear();
- bufferPool.add(buf);
- }
- }
-
- @Override
- public void close() throws IOException {
- if (!isOpen()) {
- return;
- }
-
- cleanBufferPool();
- super.close();
- }
-
- /** Clean direct buffer pool */
- private void cleanBufferPool() {
- ByteBuffer buf;
- while ((buf = bufferPool.poll()) != null) {
- Utils.freeDirectBuffer(buf);
- }
- }
-
- private class CipherState {
- private Cipher cipher;
- private boolean reset;
-
- public CipherState(Cipher cipher) {
- this.cipher = cipher;
- this.reset = false;
- }
-
- public Cipher getCipher() {
- return cipher;
- }
-
- public boolean isReset() {
- return reset;
- }
-
- public void reset(boolean reset) {
- this.reset = reset;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/input/ChannelInput.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/input/ChannelInput.java b/src/main/java/com/intel/chimera/stream/input/ChannelInput.java
deleted file mode 100644
index dc0fd5d..0000000
--- a/src/main/java/com/intel/chimera/stream/input/ChannelInput.java
+++ /dev/null
@@ -1,165 +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 com.intel.chimera.stream.input;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
-
-/**
- * The ChannelInput class takes a <code>ReadableByteChannel</code> object and
- * wraps it as <code>Input</code> object acceptable by <code>CryptoInputStream</code>.
- */
-public class ChannelInput implements Input {
- private static final int SKIP_BUFFER_SIZE = 2048;
-
- private ByteBuffer buf;
- private ReadableByteChannel channel;
-
- /**
- * Constructs the {@link com.intel.chimera.stream.input.ChannelInput}.
- *
- * @param channel the ReadableByteChannel object.
- */
- public ChannelInput(
- ReadableByteChannel channel) {
- this.channel = channel;
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#read(ByteBuffer)}.
- * Reads a sequence of bytes from input into the given buffer.
- *
- * @param dst The buffer into which bytes are to be transferred.
- * @return the total number of bytes read into the buffer, or
- * <code>-1</code> if there is no more data because the end of
- * the stream has been reached.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int read(ByteBuffer dst) throws IOException {
- return channel.read(dst);
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#skip(long)}.
- * Skips over and discards <code>n</code> bytes of data from this input
- * stream.
- *
- * @param n the number of bytes to be skipped.
- * @return the actual number of bytes skipped.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public long skip(long n) throws IOException {
- long remaining = n;
- int nr;
-
- if (n <= 0) {
- return 0;
- }
-
- int size = (int)Math.min(SKIP_BUFFER_SIZE, remaining);
- ByteBuffer skipBuffer = getSkipBuf();
- while (remaining > 0) {
- skipBuffer.clear();
- skipBuffer.limit((int)Math.min(size, remaining));
- nr = read(skipBuffer);
- if (nr < 0) {
- break;
- }
- remaining -= nr;
- }
-
- return n - remaining;
- }
-
- /**
- * Overrides the {@link Input#available()}.
- * Returns an estimate of the number of bytes that can be read (or
- * skipped over) from this input stream without blocking by the next
- * invocation of a method for this input stream. The next invocation
- * might be the same thread or another thread. A single read or skip of this
- * many bytes will not block, but may read or skip fewer bytes.
- *
- * @return an estimate of the number of bytes that can be read (or skipped
- * over) from this input stream without blocking or {@code 0} when
- * it reaches the end of the input stream.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int available() throws IOException {
- return 0;
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#read(long, byte[], int, int)}.
- * Reads up to <code>len</code> bytes of data from the input stream into
- * an array of bytes. An attempt is made to read as many as
- * <code>len</code> bytes, but a smaller number may be read.
- * The number of bytes actually read is returned as an integer.
- *
- * @param position the given position within a stream.
- * @param buffer the buffer into which the data is read.
- * @param offset the start offset in array buffer.
- * @param length the maximum number of bytes to read.
- * @return the total number of bytes read into the buffer, or
- * <code>-1</code> if there is no more data because the end of
- * the stream has been reached.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int read(long position, byte[] buffer, int offset, int length)
- throws IOException {
- throw new UnsupportedOperationException(
- "Positioned read is not supported by this implementation");
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#seek(long)}.
- * Seeks to the given offset from the start of the stream.
- * The next read() will be from that location.
- *
- * @param position the offset from the start of the stream.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void seek(long position) throws IOException {
- throw new UnsupportedOperationException(
- "Seek is not supported by this implementation");
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#seek(long)}.
- * Closes this input and releases any system resources associated
- * with the under layer input.
- *
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- channel.close();
- }
-
- private ByteBuffer getSkipBuf() {
- if (buf == null) {
- buf = ByteBuffer.allocate(SKIP_BUFFER_SIZE);
- }
- return buf;
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/input/Input.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/input/Input.java b/src/main/java/com/intel/chimera/stream/input/Input.java
deleted file mode 100644
index e9053d5..0000000
--- a/src/main/java/com/intel/chimera/stream/input/Input.java
+++ /dev/null
@@ -1,133 +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 com.intel.chimera.stream.input;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * The Input interface abstract the input source of <code>CryptoInputStream</code> so that
- * different implementation of input can be used. The implementation Input interface will usually
- * wraps an input mechanism such as <code>InputStream</code> or <code>ReadableByteChannel</code>.
- */
-public interface Input {
- /**
- * Reads a sequence of bytes from input into the given buffer.
- *
- * <p> An attempt is made to read up to <i>r</i> bytes from the input,
- * where <i>r</i> is the number of bytes remaining in the buffer, that is,
- * <tt>dst.remaining()</tt>, at the moment this method is invoked.
- *
- * <p> Suppose that a byte sequence of length <i>n</i> is read, where
- * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>.
- * This byte sequence will be transferred into the buffer so that the first
- * byte in the sequence is at index <i>p</i> and the last byte is at index
- * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>,
- * where <i>p</i> is the buffer's position at the moment this method is
- * invoked. Upon return the buffer's position will be equal to
- * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed.
- *
- * @param dst
- * The buffer into which bytes are to be transferred.
- * @return the total number of bytes read into the buffer, or
- * <code>-1</code> if there is no more data because the end of
- * the stream has been reached.
- * @throws IOException
- * If some other I/O error occurs.
- */
- int read(ByteBuffer dst) throws IOException;
-
- /**
- * Skips over and discards <code>n</code> bytes of data from this input
- * The <code>skip</code> method may, for a variety of reasons, end
- * up skipping over some smaller number of bytes, possibly <code>0</code>.
- * This may result from any of a number of conditions; reaching end of file
- * before <code>n</code> bytes have been skipped is only one possibility.
- * The actual number of bytes skipped is returned. If <code>n</code> is
- * negative, no bytes are skipped.
- *
- * <p> The <code>skip</code> method of this class creates a
- * byte array and then repeatedly reads into it until <code>n</code> bytes
- * have been read or the end of the stream has been reached. Subclasses are
- * encouraged to provide a more efficient implementation of this method.
- * For instance, the implementation may depend on the ability to seek.
- *
- * @param n the number of bytes to be skipped.
- * @return the actual number of bytes skipped.
- * @exception IOException if the stream does not support seek,
- * or if some other I/O error occurs.
- */
- long skip(long n) throws IOException;
-
- /**
- * Returns an estimate of the number of bytes that can be read (or
- * skipped over) from this input without blocking by the next
- * invocation of a method for this input stream. The next invocation
- * might be the same thread or another thread. A single read or skip of this
- * many bytes will not block, but may read or skip fewer bytes.
- *
- * <p> It is never correct to use the return value of this method to allocate
- * a buffer intended to hold all data in this stream.
- *
- * @return an estimate of the number of bytes that can be read (or skipped
- * over) from this input stream without blocking or {@code 0} when
- * it reaches the end of the input stream.
- * @exception IOException if an I/O error occurs.
- */
- int available() throws IOException;
-
- /**
- * Reads up to the specified number of bytes from a given position within a
- * stream and return the number of bytes read.
- * This does not change the current offset of the stream and is thread-safe.
- *
- * An implementation may not support positioned read. If the implementation
- * doesn't support positioned read, it throws UnsupportedOperationException.
- *
- * @param position the given position within a stream.
- * @param buffer the buffer into which the data is read.
- * @param offset the start offset in array buffer.
- * @param length the maximum number of bytes to read.
- * @return the total number of bytes read into the buffer, or
- * <code>-1</code> if there is no more data because the end of
- * the stream has been reached.
- * @throws IOException if an I/O error occurs.
- */
- int read(long position, byte[] buffer, int offset, int length)
- throws IOException;
-
- /**
- * Seeks to the given offset from the start of the stream.
- * The next read() will be from that location.
- *
- * An implementation may not support seek. If the implementation
- * doesn't support seek, it throws UnsupportedOperationException.
- *
- * @param position the offset from the start of the stream.
- * @throws IOException if an I/O error occurs.
- */
- void seek(long position) throws IOException;
-
- /**
- * Closes this input and releases any system resources associated
- * with the under layer input.
- *
- * @exception IOException if an I/O error occurs.
- */
- void close() throws IOException;
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/input/StreamInput.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/input/StreamInput.java b/src/main/java/com/intel/chimera/stream/input/StreamInput.java
deleted file mode 100644
index c7e5eeb..0000000
--- a/src/main/java/com/intel/chimera/stream/input/StreamInput.java
+++ /dev/null
@@ -1,164 +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 com.intel.chimera.stream.input;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-/**
- * The StreamInput class takes a <code>InputStream</code> object and
- * wraps it as <code>Input</code> object acceptable by <code>CryptoInputStream</code>.
- */
-public class StreamInput implements Input {
- private byte[] buf;
- private int bufferSize;
- InputStream in;
-
- /**
- * Constructs a {@link com.intel.chimera.stream.input.StreamInput}.
- *
- * @param inputStream the inputstream object.
- * @param bufferSize the buffersize.
- */
- public StreamInput(InputStream inputStream, int bufferSize) {
- this.in = inputStream;
- this.bufferSize = bufferSize;
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#read(ByteBuffer)}.
- * Reads a sequence of bytes from input into the given buffer.
- *
- * @param dst
- * The buffer into which bytes are to be transferred.
- *
- * @return the total number of bytes read into the buffer, or
- * <code>-1</code> if there is no more data because the end of
- * the stream has been reached.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int read(ByteBuffer dst) throws IOException {
- int remaining = dst.remaining();
- final byte[] tmp = getBuf();
- int read = 0;
- while (remaining > 0) {
- final int n = in.read(tmp, 0, Math.min(remaining, bufferSize));
- if (n == -1) {
- if (read == 0) {
- read = -1;
- }
- break;
- } else if (n > 0) {
- dst.put(tmp, 0, n);
- read += n;
- remaining -= n;
- }
- }
- return read;
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#skip(long)}.
- * Skips over and discards <code>n</code> bytes of data from this input
- * stream.
- *
- * @param n the number of bytes to be skipped.
- * @return the actual number of bytes skipped.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public long skip(long n) throws IOException {
- return in.skip(n);
- }
-
- /**
- * Overrides the {@link Input#available()}.
- * Returns an estimate of the number of bytes that can be read (or
- * skipped over) from this input stream without blocking by the next
- * invocation of a method for this input stream. The next invocation
- * might be the same thread or another thread. A single read or skip of this
- * many bytes will not block, but may read or skip fewer bytes.
- *
- * @return an estimate of the number of bytes that can be read (or skipped
- * over) from this input stream without blocking or {@code 0} when
- * it reaches the end of the input stream.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int available() throws IOException {
- return in.available();
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#read(long, byte[], int, int)}.
- * Reads up to <code>len</code> bytes of data from the input stream into
- * an array of bytes. An attempt is made to read as many as
- * <code>len</code> bytes, but a smaller number may be read.
- * The number of bytes actually read is returned as an integer.
- *
- * @param position the given position within a stream.
- * @param buffer the buffer into which the data is read.
- * @param offset the start offset in array buffer.
- * @param length the maximum number of bytes to read.
- * @return the total number of bytes read into the buffer, or
- * <code>-1</code> if there is no more data because the end of
- * the stream has been reached.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int read(long position, byte[] buffer, int offset, int length)
- throws IOException {
- throw new UnsupportedOperationException(
- "Positioned read is not supported by this implementation");
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#seek(long)}.
- * Seeks to the given offset from the start of the stream.
- * The next read() will be from that location.
- *
- * @param position the offset from the start of the stream.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void seek(long position) throws IOException {
- throw new UnsupportedOperationException(
- "Seek is not supported by this implementation");
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.input.Input#seek(long)}.
- * Closes this input and releases any system resources associated
- * with the under layer input.
- *
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- in.close();
- }
-
- private byte[] getBuf() {
- if (buf == null) {
- buf = new byte[bufferSize];
- }
- return buf;
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/output/ChannelOutput.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/output/ChannelOutput.java b/src/main/java/com/intel/chimera/stream/output/ChannelOutput.java
deleted file mode 100644
index 6151255..0000000
--- a/src/main/java/com/intel/chimera/stream/output/ChannelOutput.java
+++ /dev/null
@@ -1,78 +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 com.intel.chimera.stream.output;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.WritableByteChannel;
-
-/**
- * The ChannelOutput class takes a <code>WritableByteChannel</code> object and wraps it as
- * <code>Output</code> object acceptable by <code>CryptoOutputStream</code> as the output target.
- */
-public class ChannelOutput implements Output {
-
- private WritableByteChannel channel;
-
- /**
- * Constructs a {@link com.intel.chimera.stream.output.ChannelOutput}.
- *
- * @param channel the WritableByteChannel object.
- */
- public ChannelOutput(WritableByteChannel channel) {
- this.channel = channel;
- }
-
- /**
- * Overrides the {@link com.intel.chimera.stream.output.Output#write(ByteBuffer)}.
- * Writes a sequence of bytes to this output from the given buffer.
- *
- * @param src
- * The buffer from which bytes are to be retrieved.
- *
- * @return The number of bytes written, possibly zero.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int write(ByteBuffer src) throws IOException {
- return channel.write(src);
- }
-
- /**
- * Overrides the {@link Output#flush()}.
- * Flushes this output and forces any buffered output bytes
- * to be written out if the under layer output method support.
- *
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void flush() throws IOException {
- }
-
- /**
- * Overrides the {@link Output#close()}.
- * Closes this output and releases any system resources associated
- * with the under layer output.
- *
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- channel.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/stream/output/Output.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/output/Output.java b/src/main/java/com/intel/chimera/stream/output/Output.java
deleted file mode 100644
index 940e981..0000000
--- a/src/main/java/com/intel/chimera/stream/output/Output.java
+++ /dev/null
@@ -1,76 +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 com.intel.chimera.stream.output;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * The Output interface abstract the output target of <code>CryptoOutputStream</code> so that
- * different implementation of output can be used. The implementation Output interface will usually
- * wraps an output mechanism such as <code>OutputStream</code> or <code>WritableByteChannel</code>.
- */
-public interface Output {
-
- /**
- * Writes a sequence of bytes to this output from the given buffer.
- *
- * <p> An attempt is made to write up to <i>r</i> bytes to the channel,
- * where <i>r</i> is the number of bytes remaining in the buffer, that is,
- * <tt>src.remaining()</tt>, at the moment this method is invoked.
- *
- * <p> Suppose that a byte sequence of length <i>n</i> is written, where
- * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>.
- * This byte sequence will be transferred from the buffer starting at index
- * <i>p</i>, where <i>p</i> is the buffer's position at the moment this
- * method is invoked; the index of the last byte written will be
- * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>.
- * Upon return the buffer's position will be equal to
- * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed.
- *
- * @param src
- * The buffer from which bytes are to be retrieved.
- *
- * @return The number of bytes written, possibly zero.
- *
- * @throws IOException
- * If some other I/O error occurs.
- */
- int write(ByteBuffer src) throws IOException;
-
- /**
- * Flushes this output and forces any buffered output bytes
- * to be written out if the under layer output method support.
- * The general contract of <code>flush</code> is
- * that calling it is an indication that, if any bytes previously
- * written have been buffered by the implementation of the output
- * stream, such bytes should immediately be written to their
- * intended destination.
- *
- * @throws IOException if an I/O error occurs.
- */
- void flush() throws IOException;
-
- /**
- * Closes this output and releases any system resources associated
- * with the under layer output.
- *
- * @throws IOException if an I/O error occurs.
- */
- void close() throws IOException;
-}
[4/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
Posted by xu...@apache.org.
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/input/ChannelInput.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/input/ChannelInput.java b/src/main/java/org/apache/commons/crypto/stream/input/ChannelInput.java
new file mode 100644
index 0000000..ee24a0c
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/input/ChannelInput.java
@@ -0,0 +1,165 @@
+/**
+ * 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.stream.input;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+
+/**
+ * The ChannelInput class takes a <code>ReadableByteChannel</code> object and
+ * wraps it as <code>Input</code> object acceptable by <code>CryptoInputStream</code>.
+ */
+public class ChannelInput implements Input {
+ private static final int SKIP_BUFFER_SIZE = 2048;
+
+ private ByteBuffer buf;
+ private ReadableByteChannel channel;
+
+ /**
+ * Constructs the {@link org.apache.commons.crypto.stream.input.ChannelInput}.
+ *
+ * @param channel the ReadableByteChannel object.
+ */
+ public ChannelInput(
+ ReadableByteChannel channel) {
+ this.channel = channel;
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#read(ByteBuffer)}.
+ * Reads a sequence of bytes from input into the given buffer.
+ *
+ * @param dst The buffer into which bytes are to be transferred.
+ * @return the total number of bytes read into the buffer, or
+ * <code>-1</code> if there is no more data because the end of
+ * the stream has been reached.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int read(ByteBuffer dst) throws IOException {
+ return channel.read(dst);
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#skip(long)}.
+ * Skips over and discards <code>n</code> bytes of data from this input
+ * stream.
+ *
+ * @param n the number of bytes to be skipped.
+ * @return the actual number of bytes skipped.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public long skip(long n) throws IOException {
+ long remaining = n;
+ int nr;
+
+ if (n <= 0) {
+ return 0;
+ }
+
+ int size = (int)Math.min(SKIP_BUFFER_SIZE, remaining);
+ ByteBuffer skipBuffer = getSkipBuf();
+ while (remaining > 0) {
+ skipBuffer.clear();
+ skipBuffer.limit((int)Math.min(size, remaining));
+ nr = read(skipBuffer);
+ if (nr < 0) {
+ break;
+ }
+ remaining -= nr;
+ }
+
+ return n - remaining;
+ }
+
+ /**
+ * Overrides the {@link Input#available()}.
+ * Returns an estimate of the number of bytes that can be read (or
+ * skipped over) from this input stream without blocking by the next
+ * invocation of a method for this input stream. The next invocation
+ * might be the same thread or another thread. A single read or skip of this
+ * many bytes will not block, but may read or skip fewer bytes.
+ *
+ * @return an estimate of the number of bytes that can be read (or skipped
+ * over) from this input stream without blocking or {@code 0} when
+ * it reaches the end of the input stream.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int available() throws IOException {
+ return 0;
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#read(long, byte[], int, int)}.
+ * Reads up to <code>len</code> bytes of data from the input stream into
+ * an array of bytes. An attempt is made to read as many as
+ * <code>len</code> bytes, but a smaller number may be read.
+ * The number of bytes actually read is returned as an integer.
+ *
+ * @param position the given position within a stream.
+ * @param buffer the buffer into which the data is read.
+ * @param offset the start offset in array buffer.
+ * @param length the maximum number of bytes to read.
+ * @return the total number of bytes read into the buffer, or
+ * <code>-1</code> if there is no more data because the end of
+ * the stream has been reached.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int read(long position, byte[] buffer, int offset, int length)
+ throws IOException {
+ throw new UnsupportedOperationException(
+ "Positioned read is not supported by this implementation");
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#seek(long)}.
+ * Seeks to the given offset from the start of the stream.
+ * The next read() will be from that location.
+ *
+ * @param position the offset from the start of the stream.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void seek(long position) throws IOException {
+ throw new UnsupportedOperationException(
+ "Seek is not supported by this implementation");
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#seek(long)}.
+ * Closes this input and releases any system resources associated
+ * with the under layer input.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ channel.close();
+ }
+
+ private ByteBuffer getSkipBuf() {
+ if (buf == null) {
+ buf = ByteBuffer.allocate(SKIP_BUFFER_SIZE);
+ }
+ return buf;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/input/Input.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/input/Input.java b/src/main/java/org/apache/commons/crypto/stream/input/Input.java
new file mode 100644
index 0000000..a63c6ca
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/input/Input.java
@@ -0,0 +1,133 @@
+/**
+ * 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.stream.input;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * The Input interface abstract the input source of <code>CryptoInputStream</code> so that
+ * different implementation of input can be used. The implementation Input interface will usually
+ * wraps an input mechanism such as <code>InputStream</code> or <code>ReadableByteChannel</code>.
+ */
+public interface Input {
+ /**
+ * Reads a sequence of bytes from input into the given buffer.
+ *
+ * <p> An attempt is made to read up to <i>r</i> bytes from the input,
+ * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+ * <tt>dst.remaining()</tt>, at the moment this method is invoked.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+ * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * This byte sequence will be transferred into the buffer so that the first
+ * byte in the sequence is at index <i>p</i> and the last byte is at index
+ * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>,
+ * where <i>p</i> is the buffer's position at the moment this method is
+ * invoked. Upon return the buffer's position will be equal to
+ * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed.
+ *
+ * @param dst
+ * The buffer into which bytes are to be transferred.
+ * @return the total number of bytes read into the buffer, or
+ * <code>-1</code> if there is no more data because the end of
+ * the stream has been reached.
+ * @throws IOException
+ * If some other I/O error occurs.
+ */
+ int read(ByteBuffer dst) throws IOException;
+
+ /**
+ * Skips over and discards <code>n</code> bytes of data from this input
+ * The <code>skip</code> method may, for a variety of reasons, end
+ * up skipping over some smaller number of bytes, possibly <code>0</code>.
+ * This may result from any of a number of conditions; reaching end of file
+ * before <code>n</code> bytes have been skipped is only one possibility.
+ * The actual number of bytes skipped is returned. If <code>n</code> is
+ * negative, no bytes are skipped.
+ *
+ * <p> The <code>skip</code> method of this class creates a
+ * byte array and then repeatedly reads into it until <code>n</code> bytes
+ * have been read or the end of the stream has been reached. Subclasses are
+ * encouraged to provide a more efficient implementation of this method.
+ * For instance, the implementation may depend on the ability to seek.
+ *
+ * @param n the number of bytes to be skipped.
+ * @return the actual number of bytes skipped.
+ * @exception IOException if the stream does not support seek,
+ * or if some other I/O error occurs.
+ */
+ long skip(long n) throws IOException;
+
+ /**
+ * Returns an estimate of the number of bytes that can be read (or
+ * skipped over) from this input without blocking by the next
+ * invocation of a method for this input stream. The next invocation
+ * might be the same thread or another thread. A single read or skip of this
+ * many bytes will not block, but may read or skip fewer bytes.
+ *
+ * <p> It is never correct to use the return value of this method to allocate
+ * a buffer intended to hold all data in this stream.
+ *
+ * @return an estimate of the number of bytes that can be read (or skipped
+ * over) from this input stream without blocking or {@code 0} when
+ * it reaches the end of the input stream.
+ * @exception IOException if an I/O error occurs.
+ */
+ int available() throws IOException;
+
+ /**
+ * Reads up to the specified number of bytes from a given position within a
+ * stream and return the number of bytes read.
+ * This does not change the current offset of the stream and is thread-safe.
+ *
+ * An implementation may not support positioned read. If the implementation
+ * doesn't support positioned read, it throws UnsupportedOperationException.
+ *
+ * @param position the given position within a stream.
+ * @param buffer the buffer into which the data is read.
+ * @param offset the start offset in array buffer.
+ * @param length the maximum number of bytes to read.
+ * @return the total number of bytes read into the buffer, or
+ * <code>-1</code> if there is no more data because the end of
+ * the stream has been reached.
+ * @throws IOException if an I/O error occurs.
+ */
+ int read(long position, byte[] buffer, int offset, int length)
+ throws IOException;
+
+ /**
+ * Seeks to the given offset from the start of the stream.
+ * The next read() will be from that location.
+ *
+ * An implementation may not support seek. If the implementation
+ * doesn't support seek, it throws UnsupportedOperationException.
+ *
+ * @param position the offset from the start of the stream.
+ * @throws IOException if an I/O error occurs.
+ */
+ void seek(long position) throws IOException;
+
+ /**
+ * Closes this input and releases any system resources associated
+ * with the under layer input.
+ *
+ * @exception IOException if an I/O error occurs.
+ */
+ void close() throws IOException;
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/input/StreamInput.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/input/StreamInput.java b/src/main/java/org/apache/commons/crypto/stream/input/StreamInput.java
new file mode 100644
index 0000000..ac3739b
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/input/StreamInput.java
@@ -0,0 +1,164 @@
+/**
+ * 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.stream.input;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * The StreamInput class takes a <code>InputStream</code> object and
+ * wraps it as <code>Input</code> object acceptable by <code>CryptoInputStream</code>.
+ */
+public class StreamInput implements Input {
+ private byte[] buf;
+ private int bufferSize;
+ InputStream in;
+
+ /**
+ * Constructs a {@link org.apache.commons.crypto.stream.input.StreamInput}.
+ *
+ * @param inputStream the inputstream object.
+ * @param bufferSize the buffersize.
+ */
+ public StreamInput(InputStream inputStream, int bufferSize) {
+ this.in = inputStream;
+ this.bufferSize = bufferSize;
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#read(ByteBuffer)}.
+ * Reads a sequence of bytes from input into the given buffer.
+ *
+ * @param dst
+ * The buffer into which bytes are to be transferred.
+ *
+ * @return the total number of bytes read into the buffer, or
+ * <code>-1</code> if there is no more data because the end of
+ * the stream has been reached.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int read(ByteBuffer dst) throws IOException {
+ int remaining = dst.remaining();
+ final byte[] tmp = getBuf();
+ int read = 0;
+ while (remaining > 0) {
+ final int n = in.read(tmp, 0, Math.min(remaining, bufferSize));
+ if (n == -1) {
+ if (read == 0) {
+ read = -1;
+ }
+ break;
+ } else if (n > 0) {
+ dst.put(tmp, 0, n);
+ read += n;
+ remaining -= n;
+ }
+ }
+ return read;
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#skip(long)}.
+ * Skips over and discards <code>n</code> bytes of data from this input
+ * stream.
+ *
+ * @param n the number of bytes to be skipped.
+ * @return the actual number of bytes skipped.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public long skip(long n) throws IOException {
+ return in.skip(n);
+ }
+
+ /**
+ * Overrides the {@link Input#available()}.
+ * Returns an estimate of the number of bytes that can be read (or
+ * skipped over) from this input stream without blocking by the next
+ * invocation of a method for this input stream. The next invocation
+ * might be the same thread or another thread. A single read or skip of this
+ * many bytes will not block, but may read or skip fewer bytes.
+ *
+ * @return an estimate of the number of bytes that can be read (or skipped
+ * over) from this input stream without blocking or {@code 0} when
+ * it reaches the end of the input stream.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int available() throws IOException {
+ return in.available();
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#read(long, byte[], int, int)}.
+ * Reads up to <code>len</code> bytes of data from the input stream into
+ * an array of bytes. An attempt is made to read as many as
+ * <code>len</code> bytes, but a smaller number may be read.
+ * The number of bytes actually read is returned as an integer.
+ *
+ * @param position the given position within a stream.
+ * @param buffer the buffer into which the data is read.
+ * @param offset the start offset in array buffer.
+ * @param length the maximum number of bytes to read.
+ * @return the total number of bytes read into the buffer, or
+ * <code>-1</code> if there is no more data because the end of
+ * the stream has been reached.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int read(long position, byte[] buffer, int offset, int length)
+ throws IOException {
+ throw new UnsupportedOperationException(
+ "Positioned read is not supported by this implementation");
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#seek(long)}.
+ * Seeks to the given offset from the start of the stream.
+ * The next read() will be from that location.
+ *
+ * @param position the offset from the start of the stream.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void seek(long position) throws IOException {
+ throw new UnsupportedOperationException(
+ "Seek is not supported by this implementation");
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.input.Input#seek(long)}.
+ * Closes this input and releases any system resources associated
+ * with the under layer input.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ in.close();
+ }
+
+ private byte[] getBuf() {
+ if (buf == null) {
+ buf = new byte[bufferSize];
+ }
+ return buf;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/output/ChannelOutput.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/output/ChannelOutput.java b/src/main/java/org/apache/commons/crypto/stream/output/ChannelOutput.java
new file mode 100644
index 0000000..bae82a8
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/output/ChannelOutput.java
@@ -0,0 +1,78 @@
+/**
+ * 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.stream.output;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+
+/**
+ * The ChannelOutput class takes a <code>WritableByteChannel</code> object and wraps it as
+ * <code>Output</code> object acceptable by <code>CryptoOutputStream</code> as the output target.
+ */
+public class ChannelOutput implements Output {
+
+ private WritableByteChannel channel;
+
+ /**
+ * Constructs a {@link org.apache.commons.crypto.stream.output.ChannelOutput}.
+ *
+ * @param channel the WritableByteChannel object.
+ */
+ public ChannelOutput(WritableByteChannel channel) {
+ this.channel = channel;
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.output.Output#write(ByteBuffer)}.
+ * Writes a sequence of bytes to this output from the given buffer.
+ *
+ * @param src
+ * The buffer from which bytes are to be retrieved.
+ *
+ * @return The number of bytes written, possibly zero.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int write(ByteBuffer src) throws IOException {
+ return channel.write(src);
+ }
+
+ /**
+ * Overrides the {@link Output#flush()}.
+ * Flushes this output and forces any buffered output bytes
+ * to be written out if the under layer output method support.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void flush() throws IOException {
+ }
+
+ /**
+ * Overrides the {@link Output#close()}.
+ * Closes this output and releases any system resources associated
+ * with the under layer output.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ channel.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/output/Output.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/output/Output.java b/src/main/java/org/apache/commons/crypto/stream/output/Output.java
new file mode 100644
index 0000000..903fcea
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/output/Output.java
@@ -0,0 +1,76 @@
+/**
+ * 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.stream.output;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * The Output interface abstract the output target of <code>CryptoOutputStream</code> so that
+ * different implementation of output can be used. The implementation Output interface will usually
+ * wraps an output mechanism such as <code>OutputStream</code> or <code>WritableByteChannel</code>.
+ */
+public interface Output {
+
+ /**
+ * Writes a sequence of bytes to this output from the given buffer.
+ *
+ * <p> An attempt is made to write up to <i>r</i> bytes to the channel,
+ * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+ * <tt>src.remaining()</tt>, at the moment this method is invoked.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+ * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * This byte sequence will be transferred from the buffer starting at index
+ * <i>p</i>, where <i>p</i> is the buffer's position at the moment this
+ * method is invoked; the index of the last byte written will be
+ * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>.
+ * Upon return the buffer's position will be equal to
+ * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed.
+ *
+ * @param src
+ * The buffer from which bytes are to be retrieved.
+ *
+ * @return The number of bytes written, possibly zero.
+ *
+ * @throws IOException
+ * If some other I/O error occurs.
+ */
+ int write(ByteBuffer src) throws IOException;
+
+ /**
+ * Flushes this output and forces any buffered output bytes
+ * to be written out if the under layer output method support.
+ * The general contract of <code>flush</code> is
+ * that calling it is an indication that, if any bytes previously
+ * written have been buffered by the implementation of the output
+ * stream, such bytes should immediately be written to their
+ * intended destination.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ void flush() throws IOException;
+
+ /**
+ * Closes this output and releases any system resources associated
+ * with the under layer output.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ void close() throws IOException;
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/stream/output/StreamOutput.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/stream/output/StreamOutput.java b/src/main/java/org/apache/commons/crypto/stream/output/StreamOutput.java
new file mode 100644
index 0000000..beead7f
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/stream/output/StreamOutput.java
@@ -0,0 +1,101 @@
+/**
+ * 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.stream.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * The StreamOutput class takes a <code>OutputStream</code> object and wraps it as
+ * <code>Output</code> object acceptable by <code>CryptoOutputStream</code> as the output target.
+ */
+public class StreamOutput implements Output {
+ private byte[] buf;
+ private int bufferSize;
+ protected OutputStream out;
+
+ /**
+ * Constructs a {@link org.apache.commons.crypto.stream.output.StreamOutput}.
+ *
+ * @param out the OutputStream object.
+ * @param bufferSize the buffersize.
+ */
+ public StreamOutput(OutputStream out, int bufferSize) {
+ this.out = out;
+ this.bufferSize = bufferSize;
+ }
+
+ /**
+ * Overrides the {@link org.apache.commons.crypto.stream.output.Output#write(ByteBuffer)}.
+ * Writes a sequence of bytes to this output from the given buffer.
+ *
+ * @param src
+ * The buffer from which bytes are to be retrieved.
+ *
+ * @return The number of bytes written, possibly zero.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int write(ByteBuffer src) throws IOException {
+ final int len = src.remaining();
+ final byte[] buf = getBuf();
+
+ int remaining = len;
+ while(remaining > 0) {
+ final int n = Math.min(remaining, bufferSize);
+ src.get(buf, 0, n);
+ out.write(buf, 0, n);
+ remaining = src.remaining();
+ }
+
+ return len;
+ }
+
+ /**
+ * Overrides the {@link Output#flush()}.
+ * Flushes this output and forces any buffered output bytes
+ * to be written out if the under layer output method support.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ /**
+ * Overrides the {@link Output#close()}.
+ * Closes this output and releases any system resources associated
+ * with the under layer output.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ out.close();
+ }
+
+ private byte[] getBuf() {
+ if (buf == null) {
+ buf = new byte[bufferSize];
+ }
+ return buf;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/utils/IOUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/utils/IOUtils.java b/src/main/java/org/apache/commons/crypto/utils/IOUtils.java
new file mode 100644
index 0000000..58a20a5
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/utils/IOUtils.java
@@ -0,0 +1,96 @@
+/**
+ * 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.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.crypto.stream.input.Input;
+import org.apache.commons.logging.Log;
+
+/**
+ * General utility methods for working with IO.
+ */
+public class IOUtils {
+
+ /**
+ * Does the readFully based on the Input read.
+ *
+ * @param in the input stream of bytes.
+ * @param buf the buffer to be read.
+ * @param off the start offset in array buffer.
+ * @param len the maximum number of bytes to read.
+ * @throws IOException if an I/O error occurs.
+ */
+ public static void readFully(InputStream in, byte buf[],
+ int off, int len) throws IOException {
+ int toRead = len;
+ while (toRead > 0) {
+ int ret = in.read(buf, off, toRead);
+ if (ret < 0) {
+ throw new IOException( "Premature EOF from inputStream");
+ }
+ toRead -= ret;
+ off += ret;
+ }
+ }
+
+ /**
+ * Does the readFully based on Input's positioned read.
+ * This does not change the current offset of the stream and is thread-safe.
+ *
+ * @param in the input source.
+ * @param position the given position.
+ * @param buffer the buffer to be read.
+ * @param length the maximum number of bytes to read.
+ * @param offset the start offset in array buffer.
+ * @throws IOException if an I/O error occurs.
+ */
+ public static void readFully(Input in, long position,
+ byte[] buffer, int offset, int length) throws IOException {
+ int nread = 0;
+ while (nread < length) {
+ int nbytes = in.read(position+nread, buffer, offset+nread, length-nread);
+ if (nbytes < 0) {
+ throw new IOException("End of stream reached before reading fully.");
+ }
+ nread += nbytes;
+ }
+ }
+
+ /**
+ * Closes the Closeable objects and <b>ignore</b> any {@link IOException} or
+ * null pointers. Must only be used for cleanup in exception handlers.
+ *
+ * @param log the log to record problems to at debug level. Can be null.
+ * @param closeables the objects to close.
+ */
+ public static void cleanup(Log log, java.io.Closeable... closeables) {
+ for (java.io.Closeable c : closeables) {
+ if (c != null) {
+ try {
+ c.close();
+ } catch(Throwable e) {
+ if (log != null && log.isDebugEnabled()) {
+ log.debug("Exception in closing " + c, e);
+ }
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/utils/NativeCodeLoader.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/utils/NativeCodeLoader.java b/src/main/java/org/apache/commons/crypto/utils/NativeCodeLoader.java
new file mode 100644
index 0000000..475fdda
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/utils/NativeCodeLoader.java
@@ -0,0 +1,279 @@
+/**
+ * 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.utils;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Properties;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * A helper to load the native code i.e. libchimera.so.
+ * This handles the fallback to either the bundled libchimera-Linux-i386-32.so
+ * or the default java implementations where appropriate.
+ */
+public class NativeCodeLoader {
+
+ private static final Log LOG =
+ LogFactory.getLog(NativeCodeLoader.class);
+
+ private static boolean nativeCodeLoaded = false;
+
+ static {
+ // Try to load native library and set fallback flag appropriately
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("Trying to load the custom-built native-chimera library...");
+ }
+
+ try {
+ File nativeLibFile = findNativeLibrary();
+ if (nativeLibFile != null) {
+ // Load extracted or specified native library.
+ System.load(nativeLibFile.getAbsolutePath());
+ } else {
+ // Load preinstalled library (in the path -Djava.library.path)
+ System.loadLibrary("chimera");
+ }
+ LOG.debug("Loaded the native library");
+ nativeCodeLoaded = true;
+ } catch (Throwable t) {
+ // Ignore failure to load
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("Failed to load native library with error: " + t);
+ LOG.debug("java.library.path=" +
+ System.getProperty("java.library.path"));
+ }
+ }
+
+ if (!nativeCodeLoaded) {
+ LOG.warn("Unable to load native library for the platform... " +
+ "using builtin-java classes where applicable");
+ }
+ }
+
+ static File findNativeLibrary() {
+ // Try to load the library in chimera.lib.path */
+ String nativeLibraryPath = Utils
+ .getLibPath();
+ String nativeLibraryName = Utils
+ .getLibName();
+
+ // Resolve the library file name with a suffix (e.g., dll, .so, etc.)
+ if (nativeLibraryName == null)
+ nativeLibraryName = System.mapLibraryName("chimera");
+
+ if (nativeLibraryPath != null) {
+ File nativeLib = new File(nativeLibraryPath,
+ nativeLibraryName);
+ if (nativeLib.exists())
+ return nativeLib;
+ }
+
+ // Load an OS-dependent native library inside a jar file
+ nativeLibraryPath = "/org/apache/commons/crypto/native/"
+ + OSInfo.getNativeLibFolderPathForCurrentOS();
+ boolean hasNativeLib = hasResource(nativeLibraryPath + "/"
+ + nativeLibraryName);
+ if(!hasNativeLib) {
+ if (OSInfo.getOSName().equals("Mac")) {
+ // Fix for openjdk7 for Mac
+ String altName = "libchimera.jnilib";
+ if (hasResource(nativeLibraryPath + "/" + altName)) {
+ nativeLibraryName = altName;
+ hasNativeLib = true;
+ }
+ }
+ }
+
+ if (!hasNativeLib) {
+ String errorMessage = String.format(
+ "no native library is found for os.name=%s and os.arch=%s",
+ OSInfo.getOSName(), OSInfo.getArchName());
+ throw new RuntimeException(errorMessage);
+ }
+
+ // Temporary folder for the native lib. Use the value of
+ // chimera.tempdir or java.io.tmpdir
+ String tempFolder = new File(Utils.getTmpDir())
+ .getAbsolutePath();
+
+ // Extract and load a native library inside the jar file
+ return extractLibraryFile(nativeLibraryPath,
+ nativeLibraryName, tempFolder);
+ }
+
+ /**
+ * Extracts the specified library file to the target folder.
+ *
+ * @param libFolderForCurrentOS the library in chimera.lib.path.
+ * @param libraryFileName the library name.
+ * @param targetFolder Target folder for the native lib. Use the value of
+ * chimera.tempdir or java.io.tmpdir.
+ * @return the library file.
+ */
+ private static File extractLibraryFile(String libFolderForCurrentOS,
+ String libraryFileName, String targetFolder) {
+ String nativeLibraryFilePath = libFolderForCurrentOS + "/"
+ + libraryFileName;
+
+ // Attach UUID to the native library file to ensure multiple class loaders
+ // can read the libchimera multiple times.
+ String uuid = UUID.randomUUID().toString();
+ String extractedLibFileName = String.format("chimera-%s-%s-%s", getVersion(), uuid,
+ libraryFileName);
+ File extractedLibFile = new File(targetFolder, extractedLibFileName);
+
+ InputStream reader = null;
+ try {
+ // Extract a native library file into the target directory
+ reader = NativeCodeLoader.class.getResourceAsStream(nativeLibraryFilePath);
+ FileOutputStream writer = new FileOutputStream(extractedLibFile);
+ try {
+ byte[] buffer = new byte[8192];
+ int bytesRead;
+ while ((bytesRead = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, bytesRead);
+ }
+ } finally {
+ // Delete the extracted lib file on JVM exit.
+ extractedLibFile.deleteOnExit();
+
+ if (writer != null){
+ writer.close();
+ }
+
+ if (reader != null) {
+ reader.close();
+ reader = null;
+ }
+ }
+
+ // Set executable (x) flag to enable Java to load the native library
+ if (!extractedLibFile.setReadable(true) || !extractedLibFile.setExecutable(true)
+ || !extractedLibFile.setWritable(true, true)) {
+ throw new RuntimeException("Invalid path for library path");
+ }
+
+ // Check whether the contents are properly copied from the resource folder
+ {
+ InputStream nativeIn = null;
+ InputStream extractedLibIn = null;
+ try {
+ nativeIn =
+ NativeCodeLoader.class.getResourceAsStream(nativeLibraryFilePath);
+ extractedLibIn = new FileInputStream(extractedLibFile);
+ if (!contentsEquals(nativeIn, extractedLibIn))
+ throw new RuntimeException(String.format(
+ "Failed to write a native library file at %s",
+ extractedLibFile));
+ } finally {
+ if (nativeIn != null)
+ nativeIn.close();
+ if (extractedLibIn != null)
+ extractedLibIn.close();
+ }
+ }
+
+ return new File(targetFolder, extractedLibFileName);
+ } catch (IOException e) {
+ e.printStackTrace(System.err);
+ return null;
+ } finally{
+ if(reader != null){
+ try {
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the version by reading pom.properties embedded in jar.
+ * This version data is used as a suffix of a dll file extracted from the
+ * jar.
+ *
+ * @return the version string
+ */
+ public static String getVersion() {
+ URL versionFile = NativeCodeLoader.class
+ .getResource("/META-INF/maven/org.apache.commons.crypto/chimera/pom.properties");
+ if (versionFile == null)
+ versionFile = NativeCodeLoader.class
+ .getResource("/org/apache/commons/crypto/VERSION");
+
+ String version = "unknown";
+ try {
+ if (versionFile != null) {
+ Properties versionData = new Properties();
+ versionData.load(versionFile.openStream());
+ version = versionData.getProperty("version", version);
+ if (version.equals("unknown"))
+ version = versionData.getProperty("VERSION", version);
+ version = version.trim().replaceAll("[^0-9M\\.]", "");
+ }
+ } catch (IOException e) {
+ System.err.println(e);
+ }
+ return version;
+ }
+
+ private static boolean contentsEquals(InputStream in1, InputStream in2)
+ throws IOException {
+ if (!(in1 instanceof BufferedInputStream)) {
+ in1 = new BufferedInputStream(in1);
+ }
+ if (!(in2 instanceof BufferedInputStream)) {
+ in2 = new BufferedInputStream(in2);
+ }
+
+ int ch = in1.read();
+ while (ch != -1) {
+ int ch2 = in2.read();
+ if (ch != ch2)
+ return false;
+ ch = in1.read();
+ }
+ int ch2 = in2.read();
+ return ch2 == -1;
+ }
+
+ private static boolean hasResource(String path) {
+ return NativeCodeLoader.class.getResource(path) != null;
+ }
+
+ /**
+ * Checks whether native code is loaded for this platform.
+ *
+ * @return <code>true</code> if native is loaded,
+ * else <code>false</code>.
+ */
+ public static boolean isNativeCodeLoaded() {
+ return nativeCodeLoaded;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/utils/OSInfo.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/utils/OSInfo.java b/src/main/java/org/apache/commons/crypto/utils/OSInfo.java
new file mode 100644
index 0000000..67f7d56
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/utils/OSInfo.java
@@ -0,0 +1,190 @@
+/**
+ * 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.utils;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Locale;
+
+/**
+ * Provides OS name and architecture name.
+ */
+public class OSInfo {
+ private static HashMap<String, String> archMapping = new HashMap<String, String>();
+
+ /**
+ * The constant string represents for X86 architecture, the value is: {@value #X86}.*/
+ public static final String X86 = "x86";
+
+ /**
+ * The constant string represents for X86_64 architecture, the value is:{@value #X86_64}.*/
+ public static final String X86_64 = "x86_64";
+
+ /**
+ * The constant string represents for IA64_32 architecture, the value is:{@value #IA64_32}.*/
+ public static final String IA64_32 = "ia64_32";
+
+ /**
+ * The constant string represents for IA64 architecture, the value is:{@value #IA64}.*/
+ public static final String IA64 = "ia64";
+
+ /**
+ * The constant string represents for PPC architecture, the value is:{@value #PPC}.*/
+ public static final String PPC = "ppc";
+
+ /**
+ * The constant string represents for PPC64 architecture, the value is:{@value #PPC64}.*/
+ public static final String PPC64 = "ppc64";
+
+ static {
+ // x86 mappings
+ archMapping.put(X86, X86);
+ archMapping.put("i386", X86);
+ archMapping.put("i486", X86);
+ archMapping.put("i586", X86);
+ archMapping.put("i686", X86);
+ archMapping.put("pentium", X86);
+
+ // x86_64 mappings
+ archMapping.put(X86_64, X86_64);
+ archMapping.put("amd64", X86_64);
+ archMapping.put("em64t", X86_64);
+ archMapping.put("universal", X86_64); // Needed for openjdk7 in Mac
+
+ // Itenium 64-bit mappings
+ archMapping.put(IA64, IA64);
+ archMapping.put("ia64w", IA64);
+
+ // Itenium 32-bit mappings, usually an HP-UX construct
+ archMapping.put(IA64_32, IA64_32);
+ archMapping.put("ia64n", IA64_32);
+
+ // PowerPC mappings
+ archMapping.put(PPC, PPC);
+ archMapping.put("power", PPC);
+ archMapping.put("powerpc", PPC);
+ archMapping.put("power_pc", PPC);
+ archMapping.put("power_rs", PPC);
+
+ // TODO: PowerPC 64bit mappings
+ archMapping.put(PPC64, PPC64);
+ archMapping.put("power64", PPC64);
+ archMapping.put("powerpc64", PPC64);
+ archMapping.put("power_pc64", PPC64);
+ archMapping.put("power_rs64", PPC64);
+ }
+
+ public static void main(String[] args) {
+ if (args.length >= 1) {
+ if ("--os".equals(args[0])) {
+ System.out.print(getOSName());
+ return;
+ } else if ("--arch".equals(args[0])) {
+ System.out.print(getArchName());
+ return;
+ }
+ }
+
+ System.out.print(getNativeLibFolderPathForCurrentOS());
+ }
+
+ /**
+ * Gets the native lib folder.
+ *
+ * @return the current OS's native lib folder.
+ */
+ public static String getNativeLibFolderPathForCurrentOS() {
+ return getOSName() + "/" + getArchName();
+ }
+
+ /**
+ * Gets the OS name.
+ *
+ * @return the OS name.
+ */
+ public static String getOSName() {
+ return translateOSNameToFolderName(System.getProperty("os.name"));
+ }
+
+ /**
+ * Gets the architecture name.
+ *
+ * @return the architecture name.
+ */
+ public static String getArchName() {
+ // if running Linux on ARM, need to determine ABI of JVM
+ String osArch = System.getProperty("os.arch");
+ if (osArch.startsWith("arm")
+ && System.getProperty("os.name").contains("Linux")) {
+ String javaHome = System.getProperty("java.home");
+ try {
+ // determine if first JVM found uses ARM hard-float ABI
+ String[] cmdarray = {
+ "/bin/sh",
+ "-c",
+ "find '" + javaHome
+ + "' -name 'libjvm.so' | head -1 | xargs readelf -A | "
+ + "grep 'Tag_ABI_VFP_args: VFP registers'" };
+ int exitCode = Runtime.getRuntime().exec(cmdarray).waitFor();
+ if (exitCode == 0)
+ return "armhf";
+ } catch (IOException e) {
+ // ignored: fall back to "arm" arch (soft-float ABI)
+ } catch (InterruptedException e) {
+ // ignored: fall back to "arm" arch (soft-float ABI)
+ }
+ } else {
+ String lc = osArch.toLowerCase(Locale.US);
+ if (archMapping.containsKey(lc))
+ return archMapping.get(lc);
+ }
+ return translateArchNameToFolderName(osArch);
+ }
+
+ /**
+ * Translates the OS name to folder name.
+ *
+ * @param osName the OS name.
+ * @return the folder name.
+ */
+ static String translateOSNameToFolderName(String osName) {
+ if (osName.contains("Windows")) {
+ return "Windows";
+ } else if (osName.contains("Mac")) {
+ return "Mac";
+ } else if (osName.contains("Linux")) {
+ return "Linux";
+ } else if (osName.contains("AIX")) {
+ return "AIX";
+ }
+
+ else {
+ return osName.replaceAll("\\W", "");
+ }
+ }
+
+ /**
+ * Translates the architecture name to folder name.
+ *
+ * @param archName the architecture name.
+ * @return the folder name.
+ */
+ static String translateArchNameToFolderName(String archName) {
+ return archName.replaceAll("\\W", "");
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/utils/ReflectionUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/utils/ReflectionUtils.java b/src/main/java/org/apache/commons/crypto/utils/ReflectionUtils.java
new file mode 100644
index 0000000..9ffd7e8
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/utils/ReflectionUtils.java
@@ -0,0 +1,204 @@
+/**
+ * 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.utils;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.apache.commons.crypto.cipher.Cipher;
+
+/**
+ * General utility methods for working with reflection.
+ */
+public class ReflectionUtils {
+
+ private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>>
+ CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();
+
+ private static ClassLoader classLoader;
+ static {
+ classLoader = Thread.currentThread().getContextClassLoader();
+ if (classLoader == null) {
+ classLoader = Cipher.class.getClassLoader();
+ }
+ }
+
+ /**
+ * Sentinel value to store negative cache results in {@link #CACHE_CLASSES}.
+ */
+ private static final Class<?> NEGATIVE_CACHE_SENTINEL =
+ NegativeCacheSentinel.class;
+
+ /**
+ * A unique class which is used as a sentinel value in the caching
+ * for getClassByName. {@link Cipher#getClassByNameOrNull(String)}.
+ */
+ private static abstract class NegativeCacheSentinel {}
+
+ /**
+ * Uses the constructor represented by this {@code Constructor} object to
+ * create and initialize a new instance of the constructor's
+ * declaring class, with the specified initialization parameters.
+ *
+ * @param klass the Class object.
+ * @param args array of objects to be passed as arguments to
+ * the constructor call.
+ * @return a new object created by calling the constructor
+ * this object represents.
+ */
+ @SuppressWarnings("rawtypes")
+ public static <T> T newInstance(Class<T> klass, Object ... args) {
+ try {
+ Constructor<T> ctor = null;
+
+ if (args.length == 0) {
+ ctor = klass.getDeclaredConstructor(new Class[] {});
+ } else {
+ Class[] argClses = new Class[args.length];
+ for (int i = 0; i < args.length; i++) {
+ argClses[i] = args[i].getClass();
+ }
+ ctor = klass.getDeclaredConstructor(argClses);
+ }
+ ctor.setAccessible(true);
+ return ctor.newInstance(args);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Gets the value of the <code>name</code> property as a <code>Class</code>
+ * implementing the interface specified by <code>xface</code>.
+ * If no such property is specified, then <code>defaultValue</code> is
+ * returned.An exception is thrown if the returned class does not
+ * implement the named interface.
+ *
+ * @param name the class name of default implementation.
+ * @param defaultValue default value.
+ * @param xface the interface implemented by the named class.
+ * @return property value as a <code>Class</code>,
+ * or <code>defaultValue</code>.
+ */
+ public static <U> Class<? extends U> getClass(String name,
+ Class<? extends U> defaultValue,
+ Class<U> xface) {
+ try {
+ Class<?> theClass = null;
+ if (name != null && !name.isEmpty()) {
+ theClass = getClassByName(name);
+ }
+ if (theClass == null) {
+ theClass = defaultValue;
+ }
+ if (theClass != null && !xface.isAssignableFrom(theClass))
+ throw new RuntimeException(theClass+" not "+xface.getName());
+ else if (theClass != null)
+ return theClass.asSubclass(xface);
+ else
+ return null;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Gets the value of the <code>name</code> property as a <code>Class</code>.
+ * If no such property is specified, then <code>defaultValue</code> is
+ * returned.
+ *
+ * @param name the class name.
+ * @param defaultValue default value.
+ * @return property value as a <code>Class</code>,
+ * or <code>defaultValue</code>.
+ */
+ public static Class<?> getClass(String name, Class<?> defaultValue) {
+ String valueString = System.getProperty(name);
+ if (valueString == null)
+ return defaultValue;
+ try {
+ return getClassByName(valueString);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Loads a class by name.
+ *
+ * @param name the class name.
+ * @return the class object.
+ * @throws ClassNotFoundException if the class is not found.
+ */
+ public static Class<?> getClassByName(String name)
+ throws ClassNotFoundException {
+ Class<?> ret = getClassByNameOrNull(name);
+ if (ret == null) {
+ throw new ClassNotFoundException("Class " + name + " not found");
+ }
+ return ret;
+ }
+
+ /**
+ * Loads a class by name, returning null rather than throwing an exception
+ * if it couldn't be loaded. This is to avoid the overhead of creating
+ * an exception.
+ *
+ * @param name the class name.
+ * @return the class object, or null if it could not be found.
+ */
+ private static Class<?> getClassByNameOrNull(String name) {
+ Map<String, WeakReference<Class<?>>> map;
+
+ synchronized (CACHE_CLASSES) {
+ map = CACHE_CLASSES.get(classLoader);
+ if (map == null) {
+ map = Collections.synchronizedMap(
+ new WeakHashMap<String, WeakReference<Class<?>>>());
+ CACHE_CLASSES.put(classLoader, map);
+ }
+ }
+
+ Class<?> clazz = null;
+ WeakReference<Class<?>> ref = map.get(name);
+ if (ref != null) {
+ clazz = ref.get();
+ }
+
+ if (clazz == null) {
+ try {
+ clazz = Class.forName(name, true, classLoader);
+ } catch (ClassNotFoundException e) {
+ // Leave a marker that the class isn't found
+ map.put(name, new WeakReference<Class<?>>(NEGATIVE_CACHE_SENTINEL));
+ return null;
+ }
+ // two putters can race here, but they'll put the same class
+ map.put(name, new WeakReference<Class<?>>(clazz));
+ return clazz;
+ } else if (clazz == NEGATIVE_CACHE_SENTINEL) {
+ return null; // not found
+ } else {
+ // cache hit
+ return clazz;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/utils/Utils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/utils/Utils.java b/src/main/java/org/apache/commons/crypto/utils/Utils.java
new file mode 100644
index 0000000..3658adf
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/utils/Utils.java
@@ -0,0 +1,362 @@
+/**
+ * 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.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.crypto.cipher.Cipher;
+import org.apache.commons.crypto.cipher.CipherFactory;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_DEFAULT;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_DEFAULT;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_KEY;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_NAME_KEY;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_PATH_KEY;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_SYSTEM_PROPERTIES_FILE;
+import static org.apache.commons.crypto.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_TEMPDIR_KEY;
+
+/**
+ * General utility methods.
+ */
+public class Utils {
+ private static final int MIN_BUFFER_SIZE = 512;
+
+ protected static final CipherTransformation AES_CTR_NOPADDING = CipherTransformation.AES_CTR_NOPADDING;
+
+ /**
+ * For AES, the algorithm block is fixed size of 128 bits.
+ * @see http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
+ */
+ private static final int AES_BLOCK_SIZE = AES_CTR_NOPADDING.getAlgorithmBlockSize();
+
+ static {
+ loadChimeraSystemProperties();
+ }
+
+ /**
+ * loads system properties when configuration file of the name
+ * {@link #CHIMERA_SYSTEM_PROPERTIES_FILE} is found.
+ */
+ private static void loadChimeraSystemProperties() {
+ try {
+ InputStream is = Thread.currentThread().getContextClassLoader()
+ .getResourceAsStream(CHIMERA_SYSTEM_PROPERTIES_FILE);
+
+ if (is == null)
+ return; // no configuration file is found
+
+ // Load property file
+ Properties props = new Properties();
+ props.load(is);
+ is.close();
+ Enumeration<?> names = props.propertyNames();
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ if (name.startsWith("chimera.")) {
+ if (System.getProperty(name) == null) {
+ System.setProperty(name, props.getProperty(name));
+ }
+ }
+ }
+ } catch (Throwable ex) {
+ System.err.println("Could not load '"
+ + CHIMERA_SYSTEM_PROPERTIES_FILE + "' from classpath: "
+ + ex.toString());
+ }
+ }
+
+ /**
+ * Forcibly free the direct buffer.
+ *
+ * @param buffer the bytebuffer to be freed.
+ */
+ public static void freeDirectBuffer(ByteBuffer buffer) {
+ if (buffer instanceof sun.nio.ch.DirectBuffer) {
+ final sun.misc.Cleaner bufferCleaner =
+ ((sun.nio.ch.DirectBuffer) buffer).cleaner();
+ bufferCleaner.clean();
+ }
+ }
+
+ /**
+ * Reads crypto buffer size.
+ *
+ * @param props The <code>Properties</code> class represents a set of
+ * properties.
+ * @return the buffer size.
+ * */
+ public static int getBufferSize(Properties props) {
+ String bufferSizeStr = props.getProperty(
+ CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY);
+ if (bufferSizeStr == null || bufferSizeStr.isEmpty()) {
+ bufferSizeStr = System
+ .getProperty(CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY);
+ }
+ if (bufferSizeStr == null || bufferSizeStr.isEmpty()) {
+ return CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_DEFAULT;
+ } else {
+ return Integer.parseInt(bufferSizeStr);
+ }
+ }
+
+ /**
+ * Gets the cipher class.
+ *
+ * @param props The <code>Properties</code> class represents a set of
+ * properties.
+ * @return the cipher class based on the props.
+ */
+ public static String getCipherClassString(Properties props) {
+ final String configName = CHIMERA_CRYPTO_CIPHER_CLASSES_KEY;
+ return props.getProperty(configName) != null ? props.getProperty(configName) : System
+ .getProperty(configName, CHIMERA_CRYPTO_CIPHER_CLASSES_DEFAULT);
+ }
+
+ /**
+ * Gets the Jce provider.
+ *
+ * @param props The <code>Properties</code> class represents a set of
+ * properties.
+ * @return the jce provider based on the props.
+ */
+ public static String getJCEProvider(Properties props) {
+ return props.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY) != null ?
+ props.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY) :
+ System.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY);
+ }
+
+ /**
+ * Gets the random device path.
+ *
+ * @param props The <code>Properties</code> class represents a set of
+ * properties.
+ * @return the random device path based on the props.
+ */
+ public static String getRandomDevPath(Properties props) {
+ String devPath = props.getProperty(
+ CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY);
+ if (devPath == null) {
+ devPath = System.getProperty(
+ CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY,
+ CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT);
+ }
+ return devPath;
+ }
+
+ /**
+ * Gets path of native library.
+ *
+ * @return the path of native library.
+ */
+ public static String getLibPath() {
+ return System.getProperty(CHIMERA_CRYPTO_LIB_PATH_KEY);
+ }
+
+ /**
+ * Gets the file name of native library.
+ *
+ * @return the file name of native library.
+ */
+ public static String getLibName() {
+ return System.getProperty(CHIMERA_CRYPTO_LIB_NAME_KEY);
+ }
+
+ /**
+ * Gets the temp directory for extracting crypto library.
+ *
+ * @return the temp directory.
+ */
+ public static String getTmpDir() {
+ return System.getProperty(CHIMERA_CRYPTO_LIB_TEMPDIR_KEY,
+ System.getProperty("java.io.tmpdir"));
+ }
+
+ /**
+ * Checks whether the cipher is supported streaming.
+ *
+ * @param cipher the {@link org.apache.commons.crypto.cipher.Cipher} instance.
+ * @throws IOException if an I/O error occurs.
+ */
+ public static void checkStreamCipher(Cipher cipher) throws IOException {
+ if (cipher.getTransformation() != CipherTransformation.AES_CTR_NOPADDING) {
+ throw new IOException("AES/CTR/NoPadding is required");
+ }
+ }
+
+ /**
+ * Checks and floors buffer size.
+ *
+ * @param cipher the {@link org.apache.commons.crypto.cipher.Cipher} instance.
+ * @param bufferSize the buffer size.
+ * @return the remaining buffer size.
+ */
+ public static int checkBufferSize(Cipher cipher, int bufferSize) {
+ checkArgument(bufferSize >= MIN_BUFFER_SIZE,
+ "Minimum value of buffer size is " + MIN_BUFFER_SIZE + ".");
+ return bufferSize - bufferSize % cipher.getTransformation()
+ .getAlgorithmBlockSize();
+ }
+
+ /**
+ * This method is only for Counter (CTR) mode. Generally the Cipher calculates the
+ * IV and maintain encryption context internally.For example a
+ * {@link javax.crypto.Cipher} will maintain its encryption context internally
+ * when we do encryption/decryption using the Cipher#update interface.
+ * <p/>
+ * Encryption/Decryption is not always on the entire file. For example,
+ * in Hadoop, a node may only decrypt a portion of a file (i.e. a split).
+ * In these situations, the counter is derived from the file position.
+ * <p/>
+ * The IV can be calculated by combining the initial IV and the counter with
+ * a lossless operation (concatenation, addition, or XOR).
+ * @see http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29
+ *
+ * @param initIV initial IV
+ * @param counter counter for input stream position
+ * @param IV the IV for input stream position
+ */
+ public static void calculateIV(byte[] initIV, long counter, byte[] IV) {
+ checkArgument(initIV.length == AES_BLOCK_SIZE);
+ checkArgument(IV.length == AES_BLOCK_SIZE);
+
+ int i = IV.length; // IV length
+ int j = 0; // counter bytes index
+ int sum = 0;
+ while (i-- > 0) {
+ // (sum >>> Byte.SIZE) is the carry for addition
+ sum = (initIV[i] & 0xff) + (sum >>> Byte.SIZE);
+ if (j++ < 8) { // Big-endian, and long is 8 bytes length
+ sum += (byte) counter & 0xff;
+ counter >>>= 8;
+ }
+ IV[i] = (byte) sum;
+ }
+ }
+
+ /**
+ * Helper method to create a Cipher instance and throws only IOException.
+ *
+ * @param props The <code>Properties</code> class represents a set of
+ * properties.
+ * @param transformation the CipherTransformation instance.
+ * @return the Cipher instance.
+ * @throws IOException if an I/O error occurs.
+ */
+ public static Cipher getCipherInstance(CipherTransformation transformation,
+ Properties props) throws IOException {
+ try {
+ return CipherFactory.getInstance(transformation, props);
+ } catch (GeneralSecurityException e) {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to
+ * the calling method.
+ *
+ * @param expression a boolean expression.
+ * @throws IllegalArgumentException if expression is false.
+ */
+ public static void checkArgument(boolean expression) {
+ if(!expression) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Checks the truth of an expression.
+ *
+ * @param expression a boolean expression.
+ * @param errorMessage the exception message to use if the check fails;
+ * will be converted to a string using <code>String
+ * .valueOf(Object)</code>.
+ * @throws IllegalArgumentException if expression is false.
+ */
+ public static void checkArgument(boolean expression, Object errorMessage) {
+ if (!expression) {
+ throw new IllegalArgumentException(String.valueOf(errorMessage));
+ }
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling
+ * method is not null.
+ *
+ * @param reference an object reference.
+ * @return the non-null reference that was validated.
+ * @throws NullPointerException if reference is null.
+ */
+ public static <T> T checkNotNull(T reference) {
+ if(reference == null) {
+ throw new NullPointerException();
+ } else {
+ return reference;
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling
+ * instance, but not involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression.
+ * @throws IllegalStateException if expression is false.
+ */
+ public static void checkState(boolean expression) {
+ if(!expression) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Splits class names sequence into substrings, Trim each substring into an
+ * entry,and returns an list of the entries.
+ *
+ * @param clazzNames a string consist of a list of the entries joined by a
+ * delimiter.
+ * @param separator a delimiter for the input string.
+ * @return a list of class entries.
+ */
+ public static List<String> splitClassNames(String clazzNames,
+ String separator) {
+ List<String> res = new ArrayList<String>();
+ if (clazzNames == null || clazzNames.isEmpty()) {
+ return res;
+ }
+
+ for (String clazzName : clazzNames.split(separator)) {
+ clazzName = clazzName.trim();
+ if (!clazzName.isEmpty()) {
+ res.add(clazzName);
+ }
+ }
+ return res;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/utils/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/utils/package-info.java b/src/main/java/org/apache/commons/crypto/utils/package-info.java
new file mode 100644
index 0000000..7a3c334
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/utils/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+/**
+ * Utils classes
+ */
+package org.apache.commons.crypto.utils;
[2/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
Posted by xu...@apache.org.
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/org/apache/commons/crypto/random/OpensslSecureRandomNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/random/OpensslSecureRandomNative.c b/src/main/native/org/apache/commons/crypto/random/OpensslSecureRandomNative.c
new file mode 100644
index 0000000..404697f
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/random/OpensslSecureRandomNative.c
@@ -0,0 +1,335 @@
+/**
+ * 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_random.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef UNIX
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#endif
+
+#ifdef WINDOWS
+#include <windows.h>
+#endif
+
+#include "OpensslSecureRandomNative.h"
+
+#ifdef UNIX
+static void * (*dlsym_CRYPTO_malloc) (int, const char *, int);
+static void (*dlsym_CRYPTO_free) (void *);
+static int (*dlsym_CRYPTO_num_locks) (void);
+static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
+static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
+static void (*dlsym_ENGINE_load_rdrand) (void);
+static ENGINE * (*dlsym_ENGINE_by_id) (const char *);
+static int (*dlsym_ENGINE_init) (ENGINE *);
+static int (*dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
+static int (*dlsym_ENGINE_finish) (ENGINE *);
+static int (*dlsym_ENGINE_free) (ENGINE *);
+static void (*dlsym_ENGINE_cleanup) (void);
+static int (*dlsym_RAND_bytes) (unsigned char *, int);
+static unsigned long (*dlsym_ERR_get_error) (void);
+#endif
+
+#ifdef WINDOWS
+typedef void * (__cdecl *__dlsym_CRYPTO_malloc) (int, const char *, int);
+typedef void (__cdecl *__dlsym_CRYPTO_free) (void *);
+typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void);
+typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback) \
+ (void (*)(int, int, char *, int);
+typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void);
+typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id) (const char *);
+typedef int (__cdecl *__dlsym_ENGINE_init) (ENGINE *);
+typedef int (__cdecl *__dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
+typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *);
+typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *);
+typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void);
+typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int);
+typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void);
+static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc;
+static __dlsym_CRYPTO_free dlsym_CRYPTO_free;
+static __dlsym_CRYPTO_num_locks dlsym_CRYPTO_num_locks;
+static __dlsym_CRYPTO_set_locking_callback dlsym_CRYPTO_set_locking_callback;
+static __dlsym_ENGINE_load_rdrand dlsym_ENGINE_load_rdrand;
+static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id;
+static __dlsym_ENGINE_init dlsym_ENGINE_init;
+static __dlsym_ENGINE_set_default dlsym_ENGINE_set_default;
+static __dlsym_ENGINE_finish dlsym_ENGINE_finish;
+static __dlsym_ENGINE_free dlsym_ENGINE_free;
+static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup;
+static __dlsym_RAND_bytes dlsym_RAND_bytes;
+static __dlsym_ERR_get_error dlsym_ERR_get_error;
+#endif
+
+static ENGINE * openssl_rand_init(void);
+static void openssl_rand_clean(ENGINE *eng, int clean_locks);
+static int openssl_rand_bytes(unsigned char *buf, int num);
+
+JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpensslSecureRandomNative_initSR
+ (JNIEnv *env, jclass clazz)
+{
+ char msg[1000];
+#ifdef UNIX
+ void *openssl = dlopen(CHIMERA_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+#endif
+
+#ifdef WINDOWS
+ HMODULE openssl = LoadLibrary(CHIMERA_OPENSSL_LIBRARY);
+#endif
+
+ if (!openssl) {
+ snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", CHIMERA_OPENSSL_LIBRARY, \
+ dlerror());
+ THROW(env, "java/lang/UnsatisfiedLinkError", msg);
+ return;
+ }
+
+#ifdef UNIX
+ dlerror(); // Clear any existing error
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_malloc, env, openssl, "CRYPTO_malloc");
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_free, env, openssl, "CRYPTO_free");
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks");
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback, \
+ env, openssl, "CRYPTO_set_locking_callback");
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env, \
+ openssl, "CRYPTO_set_id_callback");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env, \
+ openssl, "ENGINE_load_rdrand");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_by_id, env, openssl, "ENGINE_by_id");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_init, env, openssl, "ENGINE_init");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_set_default, env, \
+ openssl, "ENGINE_set_default");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_finish, env, openssl, "ENGINE_finish");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup");
+ LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error");
+#endif
+
+#ifdef WINDOWS
+ LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_malloc, dlsym_CRYPTO_malloc, \
+ env, openssl, "CRYPTO_malloc");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_free, dlsym_CRYPTO_free, \
+ env, openssl, "CRYPTO_free");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_num_locks, dlsym_CRYPTO_num_locks, \
+ env, openssl, "CRYPTO_num_locks");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_set_locking_callback, \
+ dlsym_CRYPTO_set_locking_callback, \
+ env, openssl, "CRYPTO_set_locking_callback");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_load_rdrand, dlsym_ENGINE_load_rdrand, \
+ env, openssl, "ENGINE_load_rdrand");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id, \
+ env, openssl, "ENGINE_by_id");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_init, dlsym_ENGINE_init, \
+ env, openssl, "ENGINE_init");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_set_default, dlsym_ENGINE_set_default, \
+ env, openssl, "ENGINE_set_default");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_finish, dlsym_ENGINE_finish, \
+ env, openssl, "ENGINE_finish");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, \
+ env, openssl, "ENGINE_free");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_cleanup, dlsym_ENGINE_cleanup, \
+ env, openssl, "ENGINE_cleanup");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_RAND_bytes, dlsym_RAND_bytes, \
+ env, openssl, "RAND_bytes");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ERR_get_error, dlsym_ERR_get_error, \
+ env, openssl, "ERR_get_error");
+#endif
+
+ openssl_rand_init();
+}
+
+JNIEXPORT jboolean JNICALL Java_org_apache_commons_crypto_random_OpensslSecureRandomNative_nextRandBytes___3B
+ (JNIEnv *env, jobject object, jbyteArray bytes)
+{
+ if (NULL == bytes) {
+ THROW(env, "java/lang/NullPointerException", "Buffer cannot be null.");
+ return JNI_FALSE;
+ }
+ jbyte *b = (*env)->GetByteArrayElements(env, bytes, NULL);
+ if (NULL == b) {
+ THROW(env, "java/lang/InternalError", "Cannot get bytes array.");
+ return JNI_FALSE;
+ }
+ int b_len = (*env)->GetArrayLength(env, bytes);
+ int ret = openssl_rand_bytes((unsigned char *)b, b_len);
+ (*env)->ReleaseByteArrayElements(env, bytes, b, 0);
+
+ if (1 != ret) {
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+/**
+ * To ensure thread safety for random number generators, we need to call
+ * CRYPTO_set_locking_callback.
+ * http://wiki.openssl.org/index.php/Random_Numbers
+ * Example: crypto/threads/mttest.c
+ */
+
+#ifdef WINDOWS
+static void windows_locking_callback(int mode, int type, char *file, int line);
+static HANDLE *lock_cs;
+
+static void locks_setup(void)
+{
+ int i;
+ lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE), \
+ __FILE__, __LINE__);
+
+ for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+ lock_cs[i] = CreateMutex(NULL, FALSE, NULL);
+ }
+ dlsym_CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) \
+ windows_locking_callback);
+ /* id callback defined */
+}
+
+static void locks_cleanup(void)
+{
+ int i;
+ dlsym_CRYPTO_set_locking_callback(NULL);
+
+ for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+ CloseHandle(lock_cs[i]);
+ }
+ dlsym_CRYPTO_free(lock_cs);
+}
+
+static void windows_locking_callback(int mode, int type, char *file, int line)
+{
+ UNUSED(file), UNUSED(line);
+
+ if (mode & CRYPTO_LOCK) {
+ WaitForSingleObject(lock_cs[type], INFINITE);
+ } else {
+ ReleaseMutex(lock_cs[type]);
+ }
+}
+#endif /* WINDOWS */
+
+#ifdef UNIX
+static void pthreads_locking_callback(int mode, int type, char *file, int line);
+static unsigned long pthreads_thread_id(void);
+static pthread_mutex_t *lock_cs;
+
+static void locks_setup(void)
+{
+ int i;
+ lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * \
+ sizeof(pthread_mutex_t), __FILE__, __LINE__);
+
+ for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+ pthread_mutex_init(&(lock_cs[i]), NULL);
+ }
+
+ dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
+ dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
+}
+
+static void locks_cleanup(void)
+{
+ int i;
+ dlsym_CRYPTO_set_locking_callback(NULL);
+
+ for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+ pthread_mutex_destroy(&(lock_cs[i]));
+ }
+
+ dlsym_CRYPTO_free(lock_cs);
+}
+
+static void pthreads_locking_callback(int mode, int type, char *file, int line)
+{
+ UNUSED(file), UNUSED(line);
+
+ if (mode & CRYPTO_LOCK) {
+ pthread_mutex_lock(&(lock_cs[type]));
+ } else {
+ pthread_mutex_unlock(&(lock_cs[type]));
+ }
+}
+
+static unsigned long pthreads_thread_id(void)
+{
+ return (unsigned long)syscall(SYS_gettid);
+}
+
+#endif /* UNIX */
+
+/**
+ * If using an Intel chipset with RDRAND, the high-performance hardware
+ * random number generator will be used.
+ */
+static ENGINE * openssl_rand_init(void)
+{
+ locks_setup();
+
+ dlsym_ENGINE_load_rdrand();
+ ENGINE *eng = dlsym_ENGINE_by_id("rdrand");
+
+ int ret = -1;
+ do {
+ if (NULL == eng) {
+ break;
+ }
+
+ int rc = dlsym_ENGINE_init(eng);
+ if (0 == rc) {
+ break;
+ }
+
+ rc = dlsym_ENGINE_set_default(eng, ENGINE_METHOD_RAND);
+ if (0 == rc) {
+ break;
+ }
+
+ ret = 0;
+ } while(0);
+
+ if (ret == -1) {
+ openssl_rand_clean(eng, 0);
+ }
+
+ return eng;
+}
+
+static void openssl_rand_clean(ENGINE *eng, int clean_locks)
+{
+ if (NULL != eng) {
+ dlsym_ENGINE_finish(eng);
+ dlsym_ENGINE_free(eng);
+ }
+
+ dlsym_ENGINE_cleanup();
+ if (clean_locks) {
+ locks_cleanup();
+ }
+}
+
+static int openssl_rand_bytes(unsigned char *buf, int num)
+{
+ return dlsym_RAND_bytes(buf, num);
+}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/org/apache/commons/crypto/random/org_apache_commons_crypto_random.h
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/random/org_apache_commons_crypto_random.h b/src/main/native/org/apache/commons/crypto/random/org_apache_commons_crypto_random.h
new file mode 100644
index 0000000..7adb060
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/random/org_apache_commons_crypto_random.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef ORG_APACHE_COMMONS_CRYPTO_RANDOM_H
+#define ORG_APACHE_COMMONS_CRYPTO_RANDOM_H
+
+#include "org_apache_commons_crypto.h"
+
+#ifdef UNIX
+#include <dlfcn.h>
+#include "config.h"
+#endif
+
+#ifdef WINDOWS
+#include "winutils.h"
+#endif
+
+#define UNUSED(x) ((void)(x))
+
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#endif //ORG_APACHE_COMMONS_CRYPTO_RANDOM_H
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/cipher/AbstractCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/cipher/AbstractCipherTest.java b/src/test/java/com/intel/chimera/cipher/AbstractCipherTest.java
deleted file mode 100644
index bc69464..0000000
--- a/src/test/java/com/intel/chimera/cipher/AbstractCipherTest.java
+++ /dev/null
@@ -1,242 +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 com.intel.chimera.cipher;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.security.SecureRandom;
-import java.util.Properties;
-import java.util.Random;
-import javax.xml.bind.DatatypeConverter;
-
-import com.intel.chimera.conf.ConfigurationKeys;
-import com.intel.chimera.utils.ReflectionUtils;
-import com.intel.chimera.utils.Utils;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public abstract class AbstractCipherTest {
-
- // data
- public static final int BYTEBUFFER_SIZE = 1000;
- public String[] cipherTests = null;
- Properties props = null;
- String cipherClass = null;
- CipherTransformation[] transformations = null;
-
- // cipher
- static final byte[] KEY = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
- static final byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
- Cipher enc, dec;
-
- @Before
- public void setup() {
- init();
- Utils.checkNotNull(cipherClass);
- Utils.checkNotNull(transformations);
- props = new Properties();
- props.setProperty(ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_KEY,
- cipherClass);
- }
-
- protected abstract void init() ;
-
- @Test
- public void cryptoTest() throws GeneralSecurityException, IOException {
- for (CipherTransformation tran : transformations) {
- /** uses the small data set in {@link TestData} */
- cipherTests = TestData.getTestData(tran);
- for (int i = 0; i != cipherTests.length; i += 5) {
- byte[] key = DatatypeConverter.parseHexBinary(cipherTests[i + 1]);
- byte[] iv = DatatypeConverter.parseHexBinary(cipherTests[i + 2]);
-
- byte[] inputBytes = DatatypeConverter.parseHexBinary(cipherTests[i + 3]);
- byte[] outputBytes = DatatypeConverter.parseHexBinary(cipherTests[i + 4]);
-
- ByteBuffer inputBuffer = ByteBuffer.allocateDirect(inputBytes.length);
- ByteBuffer outputBuffer = ByteBuffer.allocateDirect(outputBytes.length);
- inputBuffer.put(inputBytes);
- inputBuffer.flip();
- outputBuffer.put(outputBytes);
- outputBuffer.flip();
-
- byteBufferTest(tran,key, iv, inputBuffer, outputBuffer);
- byteArrayTest(tran, key, iv, inputBytes, outputBytes);
- }
-
- /** uses randomly generated big data set */
- byteArrayTest(tran, KEY, IV);
- }
- }
-
- private void byteBufferTest(CipherTransformation transformation, byte[] key,
- byte[] iv,
- ByteBuffer input, ByteBuffer output) throws
- GeneralSecurityException, IOException {
- ByteBuffer decResult = ByteBuffer.allocateDirect(BYTEBUFFER_SIZE);
- ByteBuffer encResult = ByteBuffer.allocateDirect(BYTEBUFFER_SIZE);
- Cipher enc, dec;
-
- enc = getCipher(transformation);
- dec = getCipher(transformation);
-
- try {
- enc.init(Cipher.ENCRYPT_MODE, key, iv);
- } catch (Exception e) {
- Assert.fail("AES failed initialisation - " + e.toString());
- }
-
- try {
- dec.init(Cipher.DECRYPT_MODE, key, iv);
- } catch (Exception e) {
- Assert.fail("AES failed initialisation - " + e.toString());
- }
-
- //
- // encryption pass
- //
- enc.doFinal(input, encResult);
- input.flip();
- encResult.flip();
- if (!output.equals(encResult)) {
- byte[] b = new byte[output.remaining()];
- output.get(b);
- byte[] c = new byte[encResult.remaining()];
- encResult.get(c);
- Assert.fail("AES failed encryption - expected " + new String(
- DatatypeConverter
- .printHexBinary(b)) + " got " + new String(
- DatatypeConverter.printHexBinary(c)));
- }
-
- //
- // decryption pass
- //
- dec.doFinal(encResult, decResult);
- decResult.flip();
-
- if (!input.equals(decResult)) {
- byte[] inArray = new byte[input.remaining()];
- byte[] decResultArray = new byte[decResult.remaining()];
- input.get(inArray);
- decResult.get(decResultArray);
- Assert.fail();
- }
- }
-
- /** test byte array whose data is planned in {@link TestData} */
- private void byteArrayTest(CipherTransformation transformation, byte[] key,
- byte[] iv, byte[] input, byte[] output) throws GeneralSecurityException {
- resetCipher(transformation, key, iv);
- int blockSize = transformation.getAlgorithmBlockSize();
-
- byte[] temp = new byte[input.length + blockSize];
- int n = enc.doFinal(input, 0, input.length, temp, 0);
- byte[] cipherText = new byte[n];
- System.arraycopy(temp, 0, cipherText, 0, n);
- Assert.assertArrayEquals("byte array encryption error.", output, cipherText);
-
- temp = new byte[cipherText.length + blockSize];
- int m = dec.doFinal(cipherText, 0, cipherText.length, temp, 0);
- byte[] plainText = new byte[m];
- System.arraycopy(temp, 0, plainText, 0, m);
- Assert.assertArrayEquals("byte array decryption error.", input, plainText);
- }
-
- /** test byte array whose data is randomly generated */
- private void byteArrayTest(CipherTransformation transformation, byte[] key,
- byte[] iv) throws GeneralSecurityException {
- int blockSize = transformation.getAlgorithmBlockSize();
-
- // AES_CBC_NOPADDING only accepts data whose size is the multiple of block size
- int[] dataLenList = (transformation == CipherTransformation.AES_CBC_NOPADDING)
- ? new int[] {10 * 1024} : new int[] {10 * 1024, 10 * 1024 - 3};
- for (int dataLen : dataLenList) {
- byte[] plainText = new byte[dataLen];
- Random random = new SecureRandom();
- random.nextBytes(plainText);
- byte[] cipherText = new byte[dataLen + blockSize];
-
- // check update method with inputs whose sizes are the multiple of block size or not
- int[] bufferLenList = new int[] {2 * 1024 - 128, 2 * 1024 - 125};
- for (int bufferLen : bufferLenList) {
- resetCipher(transformation, key, iv);
-
- int offset = 0;
- // encrypt (update + doFinal) the data
- int cipherPos = 0;
- for (int i = 0; i < dataLen / bufferLen; i ++) {
- cipherPos += enc.update(plainText, offset, bufferLen, cipherText, cipherPos);
- offset += bufferLen;
- }
- cipherPos += enc.doFinal(plainText, offset, dataLen % bufferLen, cipherText, cipherPos);
-
- offset = 0;
- // decrypt (update + doFinal) the data
- byte[] realPlainText = new byte[cipherPos + blockSize];
- int plainPos = 0;
- for (int i = 0; i < cipherPos / bufferLen; i ++) {
- plainPos += dec.update(cipherText, offset, bufferLen, realPlainText, plainPos);
- offset += bufferLen;
- }
- plainPos += dec.doFinal(cipherText, offset, cipherPos % bufferLen, realPlainText, plainPos);
-
- // verify
- Assert.assertEquals("random byte array length changes after transformation",
- dataLen, plainPos);
-
- byte[] shrinkPlainText = new byte[plainPos];
- System.arraycopy(realPlainText, 0, shrinkPlainText, 0, plainPos);
- Assert.assertArrayEquals("random byte array contents changes after transformation",
- plainText, shrinkPlainText);
- }
- }
- }
-
- private void resetCipher(CipherTransformation transformation, byte[] key, byte[] iv) {
- enc = getCipher(transformation);
- dec = getCipher(transformation);
-
- try {
- enc.init(Cipher.ENCRYPT_MODE, key, iv);
- } catch (Exception e) {
- Assert.fail("AES failed initialisation - " + e.toString());
- }
-
- try {
- dec.init(Cipher.DECRYPT_MODE, key, iv);
- } catch (Exception e) {
- Assert.fail("AES failed initialisation - " + e.toString());
- }
- }
-
- private Cipher getCipher(CipherTransformation transformation) {
- try {
- return (Cipher) ReflectionUtils
- .newInstance(ReflectionUtils.getClassByName(cipherClass), props,
- transformation);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/cipher/JceCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/cipher/JceCipherTest.java b/src/test/java/com/intel/chimera/cipher/JceCipherTest.java
deleted file mode 100644
index 1c67c54..0000000
--- a/src/test/java/com/intel/chimera/cipher/JceCipherTest.java
+++ /dev/null
@@ -1,32 +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 com.intel.chimera.cipher;
-
-public class JceCipherTest extends AbstractCipherTest {
-
- @Override
- public void init() {
- transformations = new CipherTransformation[]{
- CipherTransformation.AES_CBC_NOPADDING,
- CipherTransformation.AES_CBC_PKCS5PADDING,
- CipherTransformation.AES_CTR_NOPADDING};
- cipherClass = JceCipher.class.getName();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/cipher/OpensslCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/cipher/OpensslCipherTest.java b/src/test/java/com/intel/chimera/cipher/OpensslCipherTest.java
deleted file mode 100644
index eae4c2c..0000000
--- a/src/test/java/com/intel/chimera/cipher/OpensslCipherTest.java
+++ /dev/null
@@ -1,165 +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 com.intel.chimera.cipher;
-
-import java.nio.ByteBuffer;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.ShortBufferException;
-
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Test;
-
-public class OpensslCipherTest extends AbstractCipherTest {
-
- @Override
- public void init() {
- transformations = new CipherTransformation[]{
- CipherTransformation.AES_CBC_NOPADDING,
- CipherTransformation.AES_CBC_PKCS5PADDING,
- CipherTransformation.AES_CTR_NOPADDING};
- cipherClass = OpensslCipher.class.getName();
- }
-
- @Test(expected = NoSuchAlgorithmException.class, timeout=120000)
- public void testInvalidAlgorithm() throws Exception {
- Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
-
- try {
- Openssl cipher = Openssl.getInstance("AES2/CTR/NoPadding");
- Assert.fail("Should specify correct algorithm.");
- } catch (NoSuchAlgorithmException e) {
- Assert.assertTrue(e.getMessage().contains("Doesn't support algorithm: AES2 and mode: CTR"));
- throw e;
- }
- }
-
- @Test(expected = NoSuchPaddingException.class, timeout=120000)
- public void testInvalidPadding() throws Exception {
- Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
-
- try {
- Openssl cipher = Openssl.getInstance("AES/CTR/NoPadding2");
- Assert.fail("Should specify correct padding.");
- } catch (NoSuchPaddingException e) {
- Assert.assertTrue(e.getMessage().contains("Doesn't support padding: NoPadding2"));
- throw e;
- }
- }
-
- @Test(expected = NoSuchAlgorithmException.class, timeout=120000)
- public void testInvalidMode() throws Exception {
- try {
- Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
- Openssl cipher = Openssl.getInstance("AES/CTR2/NoPadding");
- Assert.fail("java.security.NoSuchAlgorithmException should be thrown.");
- } catch (NoSuchAlgorithmException e) {
- Assert.assertTrue(e.getMessage().contains("Doesn't support algorithm: AES and mode: CTR2"));
- throw e;
- }
- }
-
- @Test(timeout=120000)
- public void testUpdateArguments() throws Exception {
- Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
- Openssl cipher = Openssl.getInstance(CipherTransformation.AES_CTR_NOPADDING.getName());
- Assert.assertNotNull(cipher);
-
- cipher.init(Openssl.ENCRYPT_MODE, KEY, IV);
-
- // Require direct buffers
- ByteBuffer input = ByteBuffer.allocate(1024);
- ByteBuffer output = ByteBuffer.allocate(1024);
-
- try {
- cipher.update(input, output);
- Assert.fail("Input and output buffer should be direct buffer.");
- } catch (IllegalArgumentException e) {
- Assert.assertTrue(e.getMessage().contains("Direct buffers are required"));
- }
-
- // Output buffer length should be sufficient to store output data
- input = ByteBuffer.allocateDirect(1024);
- output = ByteBuffer.allocateDirect(1000);
- try {
- cipher.update(input, output);
- Assert.fail("Output buffer length should be sufficient " +
- "to store output data");
- } catch (ShortBufferException e) {
- Assert.assertTrue(e.getMessage().contains("Output buffer is not sufficient"));
- }
- }
-
- @Test(timeout=120000)
- public void testDoFinalArguments() throws Exception {
- Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
- Openssl cipher = Openssl.getInstance(CipherTransformation.AES_CTR_NOPADDING.getName());
- Assert.assertNotNull(cipher);
-
- cipher.init(Openssl.ENCRYPT_MODE, KEY, IV);
-
- // Require direct buffer
- ByteBuffer output = ByteBuffer.allocate(1024);
-
- try {
- cipher.doFinal(output);
- Assert.fail("Output buffer should be direct buffer.");
- } catch (IllegalArgumentException e) {
- Assert.assertTrue(e.getMessage().contains("Direct buffer is required"));
- }
- }
-
- @Test(expected = InvalidKeyException.class, timeout=120000)
- public void testInvalidKey() throws Exception {
- Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
- Openssl cipher = Openssl.getInstance(CipherTransformation.AES_CTR_NOPADDING.getName());
- Assert.assertNotNull(cipher);
-
- final byte[] invalidKey = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11};
- try {
- cipher.init(Openssl.ENCRYPT_MODE, invalidKey, IV);
- Assert.fail("java.security.InvalidKeyException should be thrown.");
- } catch (Exception e) {
- Assert.assertTrue(e.getMessage().contains("Invalid key length."));
- throw e;
- }
- }
-
- @Test(expected = InvalidAlgorithmParameterException.class, timeout=120000)
- public void testInvalidIV() throws Exception {
- Assume.assumeTrue(Openssl.getLoadingFailureReason() == null);
- Openssl cipher = Openssl.getInstance(CipherTransformation.AES_CTR_NOPADDING.getName());
- Assert.assertNotNull(cipher);
-
- final byte[] invalidIV = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11};
- try {
- cipher.init(Openssl.ENCRYPT_MODE, KEY, invalidIV);
- Assert.fail("java.security.InvalidAlgorithmParameterException should be thrown.");
- } catch (Exception e) {
- Assert.assertTrue(e.getMessage().contains("Wrong IV length."));
- throw e;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/cipher/TestData.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/cipher/TestData.java b/src/test/java/com/intel/chimera/cipher/TestData.java
deleted file mode 100644
index 322ef17..0000000
--- a/src/test/java/com/intel/chimera/cipher/TestData.java
+++ /dev/null
@@ -1,160 +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 com.intel.chimera.cipher;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class TestData {
-
- private static String[] CBCNoPaddingTests = {
- /*
- * key_len,key,iv,plainText,cipherText
- */
- "128",
- "2b7e151628aed2a6abf7158809cf4f3c",
- "000102030405060708090a0b0c0d0e0f",
- "6bc1bee22e409f96e93d7e117393172a",
- "7649abac8119b246cee98e9b12e9197d",
-
- "128",
- "2b7e151628aed2a6abf7158809cf4f3c",
- "7649ABAC8119B246CEE98E9B12E9197D",
- "ae2d8a571e03ac9c9eb76fac45af8e51",
- "5086cb9b507219ee95db113a917678b2",
-
- "192",
- "603deb1015ca71be2b73aef0857d77811f352c073b6108d7",
- "9CFC4E967EDB808D679F777BC6702C7D",
- "30c81c46a35ce411e5fbc1191a0a52ef",
- "78C57E3F543A18F472756DAC2F018523",
-
- "192",
- "603deb1015ca71be2b73aef0857d77811f352c073b6108d7",
- "39F23369A9D9BACFA530E26304231461",
- "f69f2445df4f9b17ad2b417be66c3710",
- "79ECA9610F0B9AAFB8C7C2D655047A41",
-
- "256",
- "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
- "000102030405060708090a0b0c0d0e0f",
- "6bc1bee22e409f96e93d7e117393172a",
- "f58c4c04d6e5f1ba779eabfb5f7bfbd6",
-
- "256",
- "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
- "F58C4C04D6E5F1BA779EABFB5F7BFBD6",
- "ae2d8a571e03ac9c9eb76fac45af8e51",
- "9cfc4e967edb808d679f777bc6702c7d"
- };
-
- private static String[] CBCPKCS5PaddingTests = {
- /*
- * key_len,key,iv,plainText,cipherText
- */
- //Test#0 for input of 6 bytes
- "128",
- "ac5800ac3cb59c7c14f36019e43b44fe",
- "f013ce1ec901b5b60a85a986b3b72eba",
- "f6cee5ff28fd",
- "e8a846fd9718507371604504d4ca1ac7",
-
- //Test#0 for input of 15 bytes
- "128",
- "0784fa652e733cb699f250b0df2c4b41",
- "106519760fb3ef97e1ccea073b27122d",
- "6842455a2992c2e5193056a5524075",
- "56a8e0c3ee3315f913693c0ca781e917",
-
- //Test#0 for input of 16 bytes
- "128",
- "04952c3fcf497a4d449c41e8730c5d9a",
- "53549bf7d5553b727458c1abaf0ba167",
- "c9a44f6f75e98ddbca7332167f5c45e3",
- "7fa290322ca7a1a04b61a1147ff20fe66fde58510a1d0289d11c0ddf6f4decfd",
-
- //Test#0 for input of 32 bytes
- "128",
- "2ae7081caebe54909820620a44a60a0f",
- "fc5e783fbe7be12f58b1f025d82ada50",
- "1ba93ee6f83752df47909585b3f28e56693f89e169d3093eee85175ea3a46cd3",
- "7944957a99e473e2c07eb496a83ec4e55db2fb44ebdd42bb611e0def29b23a73ac37eb0f4f5d86f090f3ddce3980425a",
-
- //Test#0 for input of 33 bytes
- "128",
- "898be9cc5004ed0fa6e117c9a3099d31",
- "9dea7621945988f96491083849b068df",
- "0397f4f6820b1f9386f14403be5ac16e50213bd473b4874b9bcbf5f318ee686b1d",
- "e232cd6ef50047801ee681ec30f61d53cfd6b0bca02fd03c1b234baa10ea82ac9dab8b960926433a19ce6dea08677e34"};
-
- private static String[] cipherCTRTests = {
- /*
- * key_len,key,iv,plainText,cipherText
- */
- "128",
- "2b7e151628aed2a6abf7158809cf4f3c",
- "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
- "6bc1bee22e409f96e93d7e117393172a",
- "874d6191b620e3261bef6864990db6ce",
-
- "128",
- "2b7e151628aed2a6abf7158809cf4f3c",
- "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- "ae2d8a571e03ac9c9eb76fac45af8e51",
- "9806f66b7970fdff8617187bb9fffdff",
-
- //Test for input of 15 bytes
- "128",
- "2b7e151628aed2a6abf7158809cf4f3c",
- "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- "30c81c46a35ce411e5fbc1191a0a52",
- "5ae4df3edbd5d35e5b4f09020db03e",
-
- "256",
- "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
- "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
- "6bc1bee22e409f96e93d7e117393172a",
- "601ec313775789a5b7a7f504bbf3d228",
-
- "256",
- "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
- "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- "ae2d8a571e03ac9c9eb76fac45af8e51",
- "f443e3ca4d62b59aca84e990cacaf5c5",
-
- //Test for input of 15 bytes
- "256",
- "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
- "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- "30c81c46a35ce411e5fbc1191a0a52",
- "2b0930daa23de94ce87017ba2d8498" };
-
- private static Map<CipherTransformation, String[]> testData =
- new HashMap<CipherTransformation, String[]>();
-
- static {
- testData.put(CipherTransformation.AES_CBC_NOPADDING, CBCNoPaddingTests);
- testData.put(CipherTransformation.AES_CBC_PKCS5PADDING,
- CBCPKCS5PaddingTests);
- testData.put(CipherTransformation.AES_CTR_NOPADDING, cipherCTRTests);
- }
-
- public static String[] getTestData(CipherTransformation transformation) {
- return testData.get(transformation);
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/random/AbstractRandomTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/random/AbstractRandomTest.java b/src/test/java/com/intel/chimera/random/AbstractRandomTest.java
deleted file mode 100644
index f6ee70c..0000000
--- a/src/test/java/com/intel/chimera/random/AbstractRandomTest.java
+++ /dev/null
@@ -1,57 +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 com.intel.chimera.random;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.junit.Test;
-
-public abstract class AbstractRandomTest {
-
- public abstract SecureRandom getSecureRandom() throws IOException;
-
- @Test(timeout=120000)
- public void testRandomBytes() throws Exception {
- SecureRandom random = getSecureRandom();
- // len = 16
- checkRandomBytes(random, 16);
- // len = 32
- checkRandomBytes(random, 32);
- // len = 128
- checkRandomBytes(random, 128);
- // len = 256
- checkRandomBytes(random, 256);
- random.close();
- }
-
- /**
- * Test will timeout if secure random implementation always returns a
- * constant value.
- */
- private void checkRandomBytes(SecureRandom random, int len) {
- byte[] bytes = new byte[len];
- byte[] bytes1 = new byte[len];
- random.nextBytes(bytes);
- random.nextBytes(bytes1);
-
- while (Arrays.equals(bytes, bytes1)) {
- random.nextBytes(bytes1);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/random/TestJavaSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/random/TestJavaSecureRandom.java b/src/test/java/com/intel/chimera/random/TestJavaSecureRandom.java
deleted file mode 100644
index 154e884..0000000
--- a/src/test/java/com/intel/chimera/random/TestJavaSecureRandom.java
+++ /dev/null
@@ -1,40 +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 com.intel.chimera.random;
-
-import java.io.IOException;
-import java.util.Properties;
-
-import com.intel.chimera.conf.ConfigurationKeys;
-import static junit.framework.Assert.fail;
-
-public class TestJavaSecureRandom extends AbstractRandomTest {
-
- @Override
- public SecureRandom getSecureRandom() throws IOException {
- Properties props = new Properties();
- props.setProperty(ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY,
- JavaSecureRandom.class.getName());
- SecureRandom random = SecureRandomFactory.getSecureRandom(props);
- if ( !(random instanceof JavaSecureRandom)) {
- fail("The SecureRandom should be: " + JavaSecureRandom.class.getName());
- }
- return random;
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/random/TestOpensslSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/random/TestOpensslSecureRandom.java b/src/test/java/com/intel/chimera/random/TestOpensslSecureRandom.java
deleted file mode 100644
index 07edca5..0000000
--- a/src/test/java/com/intel/chimera/random/TestOpensslSecureRandom.java
+++ /dev/null
@@ -1,40 +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 com.intel.chimera.random;
-
-import java.io.IOException;
-import java.util.Properties;
-
-import com.intel.chimera.conf.ConfigurationKeys;
-import static junit.framework.Assert.fail;
-
-public class TestOpensslSecureRandom extends AbstractRandomTest {
-
- @Override
- public SecureRandom getSecureRandom() throws IOException {
- Properties props = new Properties();
- props.setProperty(ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_CLASSES_KEY,
- OpensslSecureRandom.class.getName());
- SecureRandom random = SecureRandomFactory.getSecureRandom(props);
- if ( !(random instanceof OpensslSecureRandom)) {
- fail("The SecureRandom should be: " + OpensslSecureRandom.class.getName());
- }
- return random;
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/random/TestOsSecureRandom.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/random/TestOsSecureRandom.java b/src/test/java/com/intel/chimera/random/TestOsSecureRandom.java
deleted file mode 100644
index 2eb9bf1..0000000
--- a/src/test/java/com/intel/chimera/random/TestOsSecureRandom.java
+++ /dev/null
@@ -1,29 +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 com.intel.chimera.random;
-
-import java.io.IOException;
-import java.util.Properties;
-
-public class TestOsSecureRandom extends AbstractRandomTest{
-
- @Override
- public SecureRandom getSecureRandom() throws IOException {
- return new OsSecureRandom(new Properties());
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/stream/AbstractCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/stream/AbstractCryptoStreamTest.java b/src/test/java/com/intel/chimera/stream/AbstractCryptoStreamTest.java
deleted file mode 100644
index 2512366..0000000
--- a/src/test/java/com/intel/chimera/stream/AbstractCryptoStreamTest.java
+++ /dev/null
@@ -1,456 +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 com.intel.chimera.stream;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.ReadableByteChannel;
-import java.security.SecureRandom;
-import java.util.Properties;
-import java.util.Random;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherTransformation;
-import com.intel.chimera.cipher.JceCipher;
-import com.intel.chimera.cipher.Openssl;
-import com.intel.chimera.cipher.OpensslCipher;
-import com.intel.chimera.utils.ReflectionUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public abstract class AbstractCryptoStreamTest {
- private static final Log LOG= LogFactory.getLog(AbstractCryptoStreamTest.class);
-
- private final int dataLen = 20000;
- private byte[] data = new byte[dataLen];
- private byte[] encData;
- private Properties props = new Properties();
- protected byte[] key = new byte[16];
- private byte[] iv = new byte[16];
- private int count = 10000;
- protected static int defaultBufferSize = 8192;
- protected static int smallBufferSize = 1024;
-
- private final String jceCipherClass = JceCipher.class.getName();
- private final String opensslCipherClass = OpensslCipher.class.getName();
- protected CipherTransformation transformation;
-
- public abstract void setUp() throws IOException;
-
- @Before
- public void before() throws IOException {
- Random random = new SecureRandom();
- random.nextBytes(data);
- random.nextBytes(key);
- random.nextBytes(iv);
- setUp();
- prepareData();
- }
-
- /** Test skip. */
- @Test(timeout=120000)
- public void testSkip() throws Exception {
- doSkipTest(jceCipherClass, false);
- doSkipTest(opensslCipherClass, false);
-
- doSkipTest(jceCipherClass, true);
- doSkipTest(opensslCipherClass, true);
- }
-
- /** Test byte buffer read with different buffer size. */
- @Test(timeout=120000)
- public void testByteBufferRead() throws Exception {
- doByteBufferRead(jceCipherClass, false);
- doByteBufferRead(opensslCipherClass, false);
-
- doByteBufferRead(jceCipherClass, true);
- doByteBufferRead(opensslCipherClass, true);
- }
-
- /** Test byte buffer write. */
- @Test(timeout=120000)
- public void testByteBufferWrite() throws Exception {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- doByteBufferWrite(jceCipherClass, baos, false);
- doByteBufferWrite(opensslCipherClass, baos, false);
-
- doByteBufferWrite(jceCipherClass, baos, true);
- doByteBufferWrite(opensslCipherClass, baos, true);
- }
-
- private void doSkipTest(String cipherClass, boolean withChannel) throws IOException {
- InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), defaultBufferSize, iv, withChannel);
- byte[] result = new byte[dataLen];
- int n1 = readAll(in, result, 0, dataLen / 3);
-
- long skipped = in.skip(dataLen / 3);
- int n2 = readAll(in, result, 0, dataLen);
-
- Assert.assertEquals(dataLen, n1 + skipped + n2);
- byte[] readData = new byte[n2];
- System.arraycopy(result, 0, readData, 0, n2);
- byte[] expectedData = new byte[n2];
- System.arraycopy(data, dataLen - n2, expectedData, 0, n2);
- Assert.assertArrayEquals(readData, expectedData);
-
- try {
- skipped = in.skip(-3);
- Assert.fail("Skip Negative length should fail.");
- } catch (IllegalArgumentException e) {
- Assert.assertTrue(e.getMessage().contains("Negative skip length"));
- }
-
- // Skip after EOF
- skipped = in.skip(3);
- Assert.assertEquals(skipped, 0);
-
- in.close();
- }
-
- private void doByteBufferRead(String cipherClass, boolean withChannel) throws Exception {
- // Default buffer size, initial buffer position is 0
- InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), defaultBufferSize, iv, withChannel);
- ByteBuffer buf = ByteBuffer.allocate(dataLen + 100);
- byteBufferReadCheck(in, buf, 0);
- in.close();
-
- // Default buffer size, initial buffer position is not 0
- in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), defaultBufferSize, iv, withChannel);
- buf.clear();
- byteBufferReadCheck(in, buf, 11);
- in.close();
-
- // Small buffer size, initial buffer position is 0
- in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), smallBufferSize, iv, withChannel);
- buf.clear();
- byteBufferReadCheck(in, buf, 0);
- in.close();
-
- // Small buffer size, initial buffer position is not 0
- in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), smallBufferSize, iv, withChannel);
- buf.clear();
- byteBufferReadCheck(in, buf, 11);
- in.close();
-
- // Direct buffer, default buffer size, initial buffer position is 0
- in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), defaultBufferSize, iv, withChannel);
- buf = ByteBuffer.allocateDirect(dataLen + 100);
- byteBufferReadCheck(in, buf, 0);
- in.close();
-
- // Direct buffer, default buffer size, initial buffer position is not 0
- in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), defaultBufferSize, iv, withChannel);
- buf.clear();
- byteBufferReadCheck(in, buf, 11);
- in.close();
-
- // Direct buffer, small buffer size, initial buffer position is 0
- in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), smallBufferSize, iv, withChannel);
- buf.clear();
- byteBufferReadCheck(in, buf, 0);
- in.close();
-
- // Direct buffer, small buffer size, initial buffer position is not 0
- in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), smallBufferSize, iv, withChannel);
- buf.clear();
- byteBufferReadCheck(in, buf, 11);
- in.close();
- }
-
- private void doByteBufferWrite(String cipherClass, ByteArrayOutputStream baos,
- boolean withChannel)
- throws Exception {
- baos.reset();
- CryptoOutputStream out =
- getCryptoOutputStream(baos, getCipher(cipherClass), defaultBufferSize,
- iv, withChannel);
- ByteBuffer buf = ByteBuffer.allocateDirect(dataLen / 2);
- buf.put(data, 0, dataLen / 2);
- buf.flip();
- int n1 = out.write(buf);
-
- buf.clear();
- buf.put(data, n1, dataLen / 3);
- buf.flip();
- int n2 = out.write(buf);
-
- buf.clear();
- buf.put(data, n1 + n2, dataLen - n1 - n2);
- buf.flip();
- int n3 = out.write(buf);
-
- Assert.assertEquals(dataLen, n1 + n2 + n3);
-
- out.flush();
-
- InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData),
- getCipher(cipherClass), defaultBufferSize, iv, withChannel);
- buf = ByteBuffer.allocate(dataLen + 100);
- byteBufferReadCheck(in, buf, 0);
- in.close();
- }
-
- private void byteBufferReadCheck(InputStream in, ByteBuffer buf,
- int bufPos) throws Exception {
- buf.position(bufPos);
- int n = ((ReadableByteChannel) in).read(buf);
- Assert.assertEquals(bufPos + n, buf.position());
- byte[] readData = new byte[n];
- buf.rewind();
- buf.position(bufPos);
- buf.get(readData);
- byte[] expectedData = new byte[n];
- System.arraycopy(data, 0, expectedData, 0, n);
- Assert.assertArrayEquals(readData, expectedData);
- }
-
- private void prepareData() throws IOException {
- Cipher cipher = null;
- try {
- cipher = (Cipher)ReflectionUtils.newInstance(
- ReflectionUtils.getClassByName(jceCipherClass), props, transformation);
- } catch (ClassNotFoundException cnfe) {
- throw new IOException("Illegal crypto cipher!");
- }
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- OutputStream out = new CryptoOutputStream(baos, cipher, defaultBufferSize, key, iv);
- out.write(data);
- out.flush();
- out.close();
- encData = baos.toByteArray();
- }
-
- protected CryptoInputStream getCryptoInputStream(ByteArrayInputStream bais,
- Cipher cipher,
- int bufferSize, byte[] iv,
- boolean withChannel) throws
- IOException {
- if (withChannel) {
- return new CryptoInputStream(Channels.newChannel(bais), cipher,
- bufferSize, key, iv);
- } else {
- return new CryptoInputStream(bais, cipher, bufferSize, key, iv);
- }
- }
-
- protected CryptoOutputStream getCryptoOutputStream(ByteArrayOutputStream baos,
- Cipher cipher,
- int bufferSize, byte[] iv,
- boolean withChannel) throws
- IOException {
- if (withChannel) {
- return new CryptoOutputStream(Channels.newChannel(baos), cipher,
- bufferSize, key, iv);
- } else {
- return new CryptoOutputStream(baos, cipher, bufferSize, key, iv);
- }
- }
-
- private int readAll(InputStream in, byte[] b, int offset, int len)
- throws IOException {
- int n = 0;
- int total = 0;
- while (n != -1) {
- total += n;
- if (total >= len) {
- break;
- }
- n = in.read(b, offset + total, len - total);
- }
-
- return total;
- }
-
- protected Cipher getCipher(String cipherClass) throws IOException {
- try {
- return (Cipher)ReflectionUtils.newInstance(
- ReflectionUtils.getClassByName(cipherClass), props, transformation);
- } catch (ClassNotFoundException cnfe) {
- throw new IOException("Illegal crypto cipher!");
- }
- }
-
- @Test
- public void testReadWrite() throws Exception {
- Assert.assertEquals(null, Openssl.getLoadingFailureReason());
- doReadWriteTest(0, jceCipherClass, jceCipherClass, iv);
- doReadWriteTest(0, opensslCipherClass, opensslCipherClass, iv);
- doReadWriteTest(count, jceCipherClass, jceCipherClass, iv);
- doReadWriteTest(count, opensslCipherClass, opensslCipherClass, iv);
- doReadWriteTest(count, jceCipherClass, opensslCipherClass, iv);
- doReadWriteTest(count, opensslCipherClass, jceCipherClass, iv);
- // Overflow test, IV: xx xx xx xx xx xx xx xx ff ff ff ff ff ff ff ff
- for(int i = 0; i < 8; i++) {
- iv[8 + i] = (byte) 0xff;
- }
- doReadWriteTest(count, jceCipherClass, jceCipherClass, iv);
- doReadWriteTest(count, opensslCipherClass, opensslCipherClass, iv);
- doReadWriteTest(count, jceCipherClass, opensslCipherClass, iv);
- doReadWriteTest(count, opensslCipherClass, jceCipherClass, iv);
- }
-
- private void doReadWriteTest(int count, String encCipherClass,
- String decCipherClass, byte[] iv) throws IOException {
- doReadWriteTestForInputStream(count, encCipherClass, decCipherClass, iv);
- doReadWriteTestForReadableByteChannel(count, encCipherClass, decCipherClass,
- iv);
- }
-
- private void doReadWriteTestForInputStream(int count, String encCipherClass,
- String decCipherClass, byte[] iv) throws IOException {
- Cipher encCipher = getCipher(encCipherClass);
- LOG.debug("Created a cipher object of type: " + encCipherClass);
-
- // Generate data
- SecureRandom random = new SecureRandom();
- byte[] originalData = new byte[count];
- byte[] decryptedData = new byte[count];
- random.nextBytes(originalData);
- LOG.debug("Generated " + count + " records");
-
- // Encrypt data
- ByteArrayOutputStream encryptedData = new ByteArrayOutputStream();
- CryptoOutputStream out =
- getCryptoOutputStream(encryptedData, encCipher, defaultBufferSize, iv,
- false);
- out.write(originalData, 0, originalData.length);
- out.flush();
- out.close();
- LOG.debug("Finished encrypting data");
-
- Cipher decCipher = getCipher(decCipherClass);
- LOG.debug("Created a cipher object of type: " + decCipherClass);
-
- // Decrypt data
- CryptoInputStream in = getCryptoInputStream(
- new ByteArrayInputStream(encryptedData.toByteArray()), decCipher,
- defaultBufferSize, iv, false);
-
- // Check
- int remainingToRead = count;
- int offset = 0;
- while (remainingToRead > 0) {
- int n = in.read(decryptedData, offset, decryptedData.length - offset);
- if (n >=0) {
- remainingToRead -= n;
- offset += n;
- }
- }
-
- Assert.assertArrayEquals("originalData and decryptedData not equal",
- originalData, decryptedData);
-
- // Decrypt data byte-at-a-time
- in = getCryptoInputStream(
- new ByteArrayInputStream(encryptedData.toByteArray()), decCipher,
- defaultBufferSize, iv, false);
-
- // Check
- DataInputStream originalIn = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(originalData)));
- int expected;
- do {
- expected = originalIn.read();
- Assert.assertEquals("Decrypted stream read by byte does not match",
- expected, in.read());
- } while (expected != -1);
-
- LOG.debug("SUCCESS! Completed checking " + count + " records");
- }
-
- private void doReadWriteTestForReadableByteChannel(int count,
- String encCipherClass,
- String decCipherClass,
- byte[] iv) throws IOException {
- Cipher encCipher = getCipher(encCipherClass);
- LOG.debug("Created a cipher object of type: " + encCipherClass);
-
- // Generate data
- SecureRandom random = new SecureRandom();
- byte[] originalData = new byte[count];
- byte[] decryptedData = new byte[count];
- random.nextBytes(originalData);
- LOG.debug("Generated " + count + " records");
-
- // Encrypt data
- ByteArrayOutputStream encryptedData = new ByteArrayOutputStream();
- CryptoOutputStream out =
- getCryptoOutputStream(encryptedData, encCipher, defaultBufferSize, iv,
- true);
- out.write(originalData, 0, originalData.length);
- out.flush();
- out.close();
- LOG.debug("Finished encrypting data");
-
- Cipher decCipher = getCipher(decCipherClass);
- LOG.debug("Created a cipher object of type: " + decCipherClass);
-
- // Decrypt data
- CryptoInputStream in = getCryptoInputStream(
- new ByteArrayInputStream(encryptedData.toByteArray()), decCipher,
- defaultBufferSize, iv, true);
-
- // Check
- int remainingToRead = count;
- int offset = 0;
- while (remainingToRead > 0) {
- int n = in.read(decryptedData, offset, decryptedData.length - offset);
- if (n >=0) {
- remainingToRead -= n;
- offset += n;
- }
- }
-
- Assert.assertArrayEquals("originalData and decryptedData not equal",
- originalData, decryptedData);
-
- // Decrypt data byte-at-a-time
- in = getCryptoInputStream(new ByteArrayInputStream(
- encryptedData.toByteArray()),decCipher,defaultBufferSize,iv,true);
-
- // Check
- DataInputStream originalIn = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(originalData)));
- int expected;
- do {
- expected = originalIn.read();
- Assert.assertEquals("Decrypted stream read by byte does not match",
- expected, in.read());
- } while (expected != -1);
-
- LOG.debug("SUCCESS! Completed checking " + count + " records");
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/stream/CBCNoPaddingCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/stream/CBCNoPaddingCryptoStreamTest.java b/src/test/java/com/intel/chimera/stream/CBCNoPaddingCryptoStreamTest.java
deleted file mode 100644
index b28922a..0000000
--- a/src/test/java/com/intel/chimera/stream/CBCNoPaddingCryptoStreamTest.java
+++ /dev/null
@@ -1,31 +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 com.intel.chimera.stream;
-
-import java.io.IOException;
-
-import com.intel.chimera.cipher.CipherTransformation;
-
-public class CBCNoPaddingCryptoStreamTest extends AbstractCryptoStreamTest {
-
- public void setUp() throws IOException {
- transformation = CipherTransformation
- .AES_CBC_NOPADDING;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/stream/CBCPKCS5PaddingCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/stream/CBCPKCS5PaddingCryptoStreamTest.java b/src/test/java/com/intel/chimera/stream/CBCPKCS5PaddingCryptoStreamTest.java
deleted file mode 100644
index ec494a0..0000000
--- a/src/test/java/com/intel/chimera/stream/CBCPKCS5PaddingCryptoStreamTest.java
+++ /dev/null
@@ -1,30 +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 com.intel.chimera.stream;
-
-import java.io.IOException;
-
-import com.intel.chimera.cipher.CipherTransformation;
-
-public class CBCPKCS5PaddingCryptoStreamTest extends AbstractCryptoStreamTest {
-
- public void setUp() throws IOException {
- transformation = CipherTransformation
- .AES_CBC_PKCS5PADDING;
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/stream/CTRCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/stream/CTRCryptoStreamTest.java b/src/test/java/com/intel/chimera/stream/CTRCryptoStreamTest.java
deleted file mode 100644
index c46f736..0000000
--- a/src/test/java/com/intel/chimera/stream/CTRCryptoStreamTest.java
+++ /dev/null
@@ -1,58 +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 com.intel.chimera.stream;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.channels.Channels;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherTransformation;
-
-public class CTRCryptoStreamTest extends AbstractCryptoStreamTest {
-
- public void setUp() throws IOException {
- transformation = CipherTransformation
- .AES_CTR_NOPADDING;
- }
-
- @Override
- protected CTRCryptoInputStream getCryptoInputStream
- (ByteArrayInputStream bais, Cipher cipher, int
- bufferSize,byte[] iv, boolean withChannel)
- throws IOException {
- if (withChannel) {
- return new CTRCryptoInputStream(Channels.newChannel(bais), cipher,
- bufferSize, key, iv);
- } else {
- return new CTRCryptoInputStream(bais, cipher, bufferSize, key, iv);
- }
- }
-
- @Override
- protected CTRCryptoOutputStream getCryptoOutputStream(ByteArrayOutputStream baos,Cipher cipher, int
- bufferSize, byte[] iv, boolean withChannel)
- throws IOException {
- if (withChannel) {
- return new CTRCryptoOutputStream(Channels.newChannel(baos), cipher, bufferSize, key, iv);
- } else {
- return new CTRCryptoOutputStream(baos, cipher, bufferSize, key, iv);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/stream/CTRNoPaddingCryptoStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/stream/CTRNoPaddingCryptoStreamTest.java b/src/test/java/com/intel/chimera/stream/CTRNoPaddingCryptoStreamTest.java
deleted file mode 100644
index f044cca..0000000
--- a/src/test/java/com/intel/chimera/stream/CTRNoPaddingCryptoStreamTest.java
+++ /dev/null
@@ -1,31 +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 com.intel.chimera.stream;
-
-import java.io.IOException;
-
-import com.intel.chimera.cipher.CipherTransformation;
-
-public class CTRNoPaddingCryptoStreamTest extends AbstractCryptoStreamTest {
-
- public void setUp() throws IOException {
- transformation = CipherTransformation
- .AES_CTR_NOPADDING;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/stream/PositionedCryptoInputStreamTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/stream/PositionedCryptoInputStreamTest.java b/src/test/java/com/intel/chimera/stream/PositionedCryptoInputStreamTest.java
deleted file mode 100644
index eae4272..0000000
--- a/src/test/java/com/intel/chimera/stream/PositionedCryptoInputStreamTest.java
+++ /dev/null
@@ -1,381 +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 com.intel.chimera.stream;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherTransformation;
-import com.intel.chimera.cipher.JceCipher;
-import com.intel.chimera.cipher.OpensslCipher;
-import com.intel.chimera.stream.input.Input;
-import com.intel.chimera.utils.ReflectionUtils;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Properties;
-import java.util.Random;
-
-public class PositionedCryptoInputStreamTest {
-
- private final int dataLen = 20000;
- private byte[] testData = new byte[dataLen];
- private byte[] encData;
- private Properties props = new Properties();
- private byte[] key = new byte[16];
- private byte[] iv = new byte[16];
- int bufferSize = 2048;
- int bufferSizeLess = bufferSize - 1;
- int bufferSizeMore = bufferSize + 1;
- int length = 1024;
- int lengthLess = length - 1;
- int lengthMore = length + 1;
-
- private final String jceCipherClass = JceCipher.class.getName();
- private final String opensslCipherClass = OpensslCipher.class.getName();
- private CipherTransformation transformation =
- CipherTransformation.AES_CTR_NOPADDING;
-
- @Before
- public void before() throws IOException {
- Random random = new SecureRandom();
- random.nextBytes(testData);
- random.nextBytes(key);
- random.nextBytes(iv);
- prepareData();
- }
-
- private void prepareData() throws IOException {
- Cipher cipher = null;
- try {
- cipher = (Cipher)ReflectionUtils.newInstance(
- ReflectionUtils.getClassByName(jceCipherClass),
- props, transformation);
- } catch (ClassNotFoundException cnfe) {
- throw new IOException("Illegal crypto cipher!");
- }
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- // encryption data
- OutputStream out = new CryptoOutputStream(baos, cipher, bufferSize, key, iv);
- out.write(testData);
- out.flush();
- out.close();
- encData = baos.toByteArray();
- }
-
- public void setUp() throws IOException {}
-
- private PositionedCryptoInputStream getCryptoInputStream(Cipher cipher,
- int bufferSize) throws IOException {
- return new PositionedCryptoInputStream(new PositionedInputForTest(
- Arrays.copyOf(encData, encData.length)), cipher, bufferSize, key, iv, 0);
- }
-
- @Test
- public void doTest() throws Exception {
- testCipher(jceCipherClass);
- testCipher(opensslCipherClass);
- }
-
- private void testCipher(String cipherClass) throws Exception {
- doPositionedReadTests(cipherClass);
- doReadFullyTests(cipherClass);
- doSeekTests(cipherClass);
- doMultipleReadTest(cipherClass);
- }
-
- // when there are multiple positioned read actions and one read action,
- // they will not interfere each other.
- private void doMultipleReadTest(String cipherClass) throws Exception {
- PositionedCryptoInputStream in = getCryptoInputStream(
- getCipher(cipherClass), bufferSize);
- int position = 0;
- while (in.available() > 0) {
- ByteBuffer buf = ByteBuffer.allocate(length);
- byte[] bytes1 = new byte[length];
- byte[] bytes2 = new byte[lengthLess];
- // do the read and position read
- int pn1 = in.read(position, bytes1, 0, length);
- int n = in.read(buf);
- int pn2 = in.read(position, bytes2, 0, lengthLess);
-
- // verify the result
- if (pn1 > 0) {
- compareByteArray(testData, position, bytes1, pn1);
- }
-
- if (pn2 > 0) {
- compareByteArray(testData, position, bytes2, pn2);
- }
-
- if (n > 0) {
- compareByteArray(testData, position, buf.array(), n);
- position += n;
- } else {
- break;
- }
- }
- in.close();
- }
-
- private void doPositionedReadTests(String cipherClass) throws Exception {
- // test with different bufferSize when position = 0
- testPositionedReadLoop(cipherClass, 0, length, bufferSize, dataLen);
- testPositionedReadLoop(cipherClass, 0, length, bufferSizeLess, dataLen);
- testPositionedReadLoop(cipherClass, 0, length, bufferSizeMore, dataLen);
- // test with different position when bufferSize = 2048
- testPositionedReadLoop(cipherClass, dataLen / 2, length, bufferSize, dataLen);
- testPositionedReadLoop(cipherClass, dataLen / 2 - 1, length,
- bufferSizeLess, dataLen);
- testPositionedReadLoop(cipherClass, dataLen / 2 + 1, length,
- bufferSizeMore, dataLen);
- // position = -1 or position = max length, read nothing and return -1
- testPositionedReadNone(cipherClass, -1, length, bufferSize);
- testPositionedReadNone(cipherClass, dataLen, length, bufferSize);
- }
-
- private void doReadFullyTests(String cipherClass) throws Exception {
- // test with different bufferSize when position = 0
- testReadFullyLoop(cipherClass, 0, length, bufferSize, dataLen);
- testReadFullyLoop(cipherClass, 0, length, bufferSizeLess, dataLen);
- testReadFullyLoop(cipherClass, 0, length, bufferSizeMore, dataLen);
- // test with different length when position = 0
- testReadFullyLoop(cipherClass, 0, length, bufferSize, dataLen);
- testReadFullyLoop(cipherClass, 0, lengthLess, bufferSize, dataLen);
- testReadFullyLoop(cipherClass, 0, lengthMore, bufferSize, dataLen);
- // test read fully failed
- testReadFullyFailed(cipherClass, -1, length, bufferSize);
- testReadFullyFailed(cipherClass, dataLen, length, bufferSize);
- testReadFullyFailed(cipherClass, dataLen - length + 1, length, bufferSize);
- }
-
- private void doSeekTests(String cipherClass) throws Exception {
- // test with different length when position = 0
- testSeekLoop(cipherClass, 0, length, bufferSize);
- testSeekLoop(cipherClass, 0, lengthLess, bufferSize);
- testSeekLoop(cipherClass, 0, lengthMore, bufferSize);
- // there should be none data read when position = dataLen
- testSeekLoop(cipherClass, dataLen, length, bufferSize);
- // test exception when position = -1
- testSeekFailed(cipherClass, -1, bufferSize);
- }
-
- private void testSeekLoop(String cipherClass, int position, int length,
- int bufferSize) throws Exception {
- PositionedCryptoInputStream in = getCryptoInputStream(
- getCipher(cipherClass), bufferSize);
- while (in.available() > 0) {
- in.seek(position);
- ByteBuffer buf = ByteBuffer.allocate(length);
- int n = in.read(buf);
- if (n > 0) {
- compareByteArray(testData, position, buf.array(), n);
- position += n;
- } else {
- break;
- }
- }
- in.close();
- }
-
- // test for the out of index position, eg, -1.
- private void testSeekFailed(String cipherClass, int position,
- int bufferSize) throws Exception {
- PositionedCryptoInputStream in = getCryptoInputStream(
- getCipher(cipherClass), bufferSize);
- try {
- in.seek(position);
- Assert.fail("Excepted exception for cannot seek to negative offset.");
- } catch (IllegalArgumentException iae) {
- }
- in.close();
- }
-
- private void testPositionedReadLoop(String cipherClass, int position,
- int length, int bufferSize, int total) throws Exception {
- PositionedCryptoInputStream in = getCryptoInputStream(
- getCipher(cipherClass), bufferSize);
- // do the position read until the end of data
- while (position < total) {
- byte[] bytes = new byte[length];
- int n = in.read(position, bytes, 0, length);
- if (n >= 0) {
- compareByteArray(testData, position, bytes, n);
- position += n;
- } else {
- break;
- }
- }
- in.close();
- }
-
- // test for the out of index position, eg, -1.
- private void testPositionedReadNone(String cipherClass, int position,
- int length, int bufferSize) throws Exception {
- PositionedCryptoInputStream in = getCryptoInputStream(
- getCipher(cipherClass), bufferSize);
- byte[] bytes = new byte[length];
- int n = in.read(position, bytes, 0, length);
- Assert.assertEquals(n, -1);
- in.close();
- }
-
- private void testReadFullyLoop(String cipherClass,int position,
- int length, int bufferSize, int total) throws Exception {
- PositionedCryptoInputStream in = getCryptoInputStream(
- getCipher(cipherClass), bufferSize);
-
- // do the position read full until remain < length
- while (position + length <= total) {
- byte[] bytes = new byte[length];
- in.readFully(position, bytes, 0, length);
- compareByteArray(testData, position, bytes, length);
- position += length;
- }
-
- in.close();
- }
-
- // test for the End of file reached before reading fully
- private void testReadFullyFailed(String cipherClass, int position,
- int length, int bufferSize) throws Exception {
- PositionedCryptoInputStream in = getCryptoInputStream(
- getCipher(cipherClass), bufferSize);
- byte[] bytes = new byte[length];
- try {
- in.readFully(position, bytes, 0, length);
- Assert.fail("Excepted EOFException.");
- } catch (IOException ioe) {
- // excepted exception
- }
- in.close();
- }
-
- // compare the data from pos with length and data2 from 0 with length
- private void compareByteArray(byte[] data1, int pos, byte[] data2, int length) {
- byte[] expectedData = new byte[length];
- byte[] realData = new byte[length];
- // get the expected data with the position and length
- System.arraycopy(data1, pos, expectedData, 0, length);
- // get the real data
- System.arraycopy(data2, 0, realData, 0, length);
- Assert.assertArrayEquals(expectedData, realData);
- }
-
- private Cipher getCipher(String cipherClass) throws IOException {
- try {
- return (Cipher)ReflectionUtils.newInstance(
- ReflectionUtils.getClassByName(cipherClass), props, transformation);
- } catch (ClassNotFoundException cnfe) {
- throw new IOException("Illegal crypto cipher!");
- }
- }
-
- class PositionedInputForTest implements Input {
-
- byte[] data;
- long pos;
- long count;
-
- public PositionedInputForTest(byte[] data) {
- this.data = data;
- this.pos = 0;
- this.count = data.length;
- }
-
- @Override
- public int read(ByteBuffer dst) throws IOException {
- int remaining = (int)(count - pos);
- if(remaining <= 0) {
- return -1;
- }
-
- int length = Math.min(dst.remaining(), remaining);
- dst.put(data, (int)pos, length);
- pos += length;
- return length;
- }
-
- @Override
- public long skip(long n) throws IOException {
- if (n <= 0) {
- return 0;
- }
-
- long remaining = count - pos;
- if(remaining < n) {
- n = remaining;
- }
- pos += n;
-
- return n;
- }
-
- @Override
- public int read(long position, byte[] buffer, int offset, int length)
- throws IOException {
- if (buffer == null) {
- throw new NullPointerException();
- } else if (offset < 0 || length < 0 || length > buffer.length - offset) {
- throw new IndexOutOfBoundsException();
- }
-
- if (position < 0 || position >= count) {
- return -1;
- }
-
- long avail = count - position;
- if (length > avail) {
- length = (int)avail;
- }
- if (length <= 0) {
- return 0;
- }
- System.arraycopy(data, (int)position, buffer, offset, length);
- return length;
- }
-
- @Override
- public void seek(long position) throws IOException {
- if (pos < 0) {
- throw new IOException("Negative seek offset");
- } else if (position >= 0 && position < count) {
- pos = position;
- } else {
- // to the end of file
- pos = count;
- }
- }
-
- @Override
- public void close() throws IOException {
- }
-
- @Override
- public int available() throws IOException {
- return (int)(count - pos);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/test/java/com/intel/chimera/utils/UtilsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/intel/chimera/utils/UtilsTest.java b/src/test/java/com/intel/chimera/utils/UtilsTest.java
deleted file mode 100644
index 8a905bb..0000000
--- a/src/test/java/com/intel/chimera/utils/UtilsTest.java
+++ /dev/null
@@ -1,40 +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 com.intel.chimera.utils;
-
-import junit.framework.Assert;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-public class UtilsTest {
- @Test
- public void testSplitOmitEmptyLine() {
- List<String> clazzNames = Utils.splitClassNames("", ",");
- Assert.assertEquals(Collections.<String>emptyList(), clazzNames);
-
- clazzNames = Utils.splitClassNames("a,b", ",");
- Assert.assertEquals(Arrays.asList("a", "b"), clazzNames);
- clazzNames = Utils.splitClassNames("a,b,", ",");
- Assert.assertEquals(Arrays.asList("a", "b"), clazzNames);
- clazzNames = Utils.splitClassNames("a, b,", ",");
- Assert.assertEquals(Arrays.asList("a", "b"), clazzNames);
- }
-}