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:34 UTC
[6/8] commons-crypto git commit: CRYPTO-7: Rename source code in
Chimera to Apache name space
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();
+ }
+}