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; -}