You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2022/12/11 17:26:36 UTC
[commons-crypto] branch master updated: Reuse own API and use ternary expressions
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-crypto.git
The following commit(s) were added to refs/heads/master by this push:
new d669943 Reuse own API and use ternary expressions
d669943 is described below
commit d669943573a9ef2df1f684e32f81ffe1e09b08fd
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Dec 11 12:26:32 2022 -0500
Reuse own API and use ternary expressions
---
.../crypto/stream/PositionedCryptoInputStream.java | 352 ++++++++++-----------
.../org/apache/commons/crypto/utils/Utils.java | 4 +-
2 files changed, 170 insertions(+), 186 deletions(-)
diff --git a/src/main/java/org/apache/commons/crypto/stream/PositionedCryptoInputStream.java b/src/main/java/org/apache/commons/crypto/stream/PositionedCryptoInputStream.java
index a0e7b04..632a552 100644
--- a/src/main/java/org/apache/commons/crypto/stream/PositionedCryptoInputStream.java
+++ b/src/main/java/org/apache/commons/crypto/stream/PositionedCryptoInputStream.java
@@ -28,7 +28,6 @@ import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.crypto.cipher.CryptoCipher;
-import org.apache.commons.crypto.cipher.CryptoCipherFactory;
import org.apache.commons.crypto.stream.input.Input;
import org.apache.commons.crypto.utils.AES;
import org.apache.commons.crypto.utils.IoUtils;
@@ -41,15 +40,58 @@ import org.apache.commons.crypto.utils.Utils;
*/
public class PositionedCryptoInputStream extends CtrCryptoInputStream {
+ private static class CipherState {
+
+ private final CryptoCipher cryptoCipher;
+ private boolean reset;
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param cryptoCipher the CryptoCipher instance.
+ */
+ public CipherState(final CryptoCipher cryptoCipher) {
+ this.cryptoCipher = cryptoCipher;
+ this.reset = false;
+ }
+
+ /**
+ * Gets the CryptoCipher instance.
+ *
+ * @return the cipher.
+ */
+ public CryptoCipher getCryptoCipher() {
+ return cryptoCipher;
+ }
+
+ /**
+ * Gets the reset.
+ *
+ * @return the value of reset.
+ */
+ public boolean isReset() {
+ return reset;
+ }
+
+ /**
+ * Sets the value of reset.
+ *
+ * @param reset the reset.
+ */
+ public void reset(final boolean reset) {
+ this.reset = reset;
+ }
+ }
+
/**
* DirectBuffer pool
*/
- private final Queue<ByteBuffer> bufferPool = new ConcurrentLinkedQueue<>();
+ private final Queue<ByteBuffer> byteBufferPool = new ConcurrentLinkedQueue<>();
/**
* CryptoCipher pool
*/
- private final Queue<CipherState> cipherPool = new ConcurrentLinkedQueue<>();
+ private final Queue<CipherState> cipherStatePool = new ConcurrentLinkedQueue<>();
/**
* properties for constructing a CryptoCipher
@@ -93,62 +135,60 @@ public class PositionedCryptoInputStream extends CtrCryptoInputStream {
this.properties = properties;
}
- /**
- * 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.
- *
- * @param buffer the buffer into which the data is read.
- * @param length the maximum number of bytes to read.
- * @param offset the start offset in the data.
- * @param position the offset from the start of the stream.
- * @throws IOException if an I/O error occurs.
- * @return int the total number of decrypted data bytes read into the
- * buffer.
- */
- public int read(final long position, final byte[] buffer, final int offset, final 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);
+ /** Cleans direct buffer pool */
+ private void cleanBufferPool() {
+ ByteBuffer buf;
+ while ((buf = byteBufferPool.poll()) != null) {
+ CryptoInputStream.freeDirectBuffer(buf);
}
- return n;
}
/**
- * Reads 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.
+ * Overrides the {@link CryptoInputStream#close()}. Closes this input stream
+ * and releases any system resources associated with the stream.
*
- * @param buffer the buffer into which the data is read.
- * @param length the maximum number of bytes to read.
- * @param offset the start offset in the data.
- * @param position the offset from the start of the stream.
* @throws IOException if an I/O error occurs.
*/
- public void readFully(final long position, final byte[] buffer, final int offset, final 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);
+ @Override
+ public void close() throws IOException {
+ if (!isOpen()) {
+ return;
}
+
+ cleanBufferPool();
+ super.close();
}
/**
- * Reads 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.
+ * Does 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().
*
- * @param position the offset from the start of the stream.
- * @param buffer the buffer into which the data is read.
+ * @param state the CipherState instance.
+ * @param inByteBuffer the input buffer.
+ * @param outByteBuffer the output buffer.
+ * @param padding the padding.
* @throws IOException if an I/O error occurs.
*/
- public void readFully(final long position, final byte[] buffer) throws IOException {
- readFully(position, buffer, 0, buffer.length);
+ private void decrypt(final CipherState state, final ByteBuffer inByteBuffer,
+ final ByteBuffer outByteBuffer, final byte padding) throws IOException {
+ Utils.checkState(inByteBuffer.position() >= padding);
+ if (inByteBuffer.position() == padding) {
+ // There is no real data in inBuffer.
+ return;
+ }
+ inByteBuffer.flip();
+ outByteBuffer.clear();
+ decryptBuffer(state, inByteBuffer, outByteBuffer);
+ inByteBuffer.clear();
+ outByteBuffer.flip();
+ if (padding > 0) {
+ /*
+ * The plain text and cipher text have a 1:1 mapping, they start at
+ * the same position.
+ */
+ outByteBuffer.position(padding);
+ }
}
/**
@@ -186,41 +226,9 @@ public class PositionedCryptoInputStream extends CtrCryptoInputStream {
padding = postDecryption(state, inByteBuffer, position + n, iv);
}
} finally {
- returnBuffer(inByteBuffer);
- returnBuffer(outByteBuffer);
- returnCipherState(state);
- }
- }
-
- /**
- * Does 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().
- *
- * @param state the CipherState instance.
- * @param inByteBuffer the input buffer.
- * @param outByteBuffer the output buffer.
- * @param padding the padding.
- * @throws IOException if an I/O error occurs.
- */
- private void decrypt(final CipherState state, final ByteBuffer inByteBuffer,
- final ByteBuffer outByteBuffer, final byte padding) throws IOException {
- Utils.checkState(inByteBuffer.position() >= padding);
- if (inByteBuffer.position() == padding) {
- // There is no real data in inBuffer.
- return;
- }
- inByteBuffer.flip();
- outByteBuffer.clear();
- decryptBuffer(state, inByteBuffer, outByteBuffer);
- inByteBuffer.clear();
- outByteBuffer.flip();
- if (padding > 0) {
- /*
- * The plain text and cipher text have a 1:1 mapping, they start at
- * the same position.
- */
- outByteBuffer.position(padding);
+ returnToPool(inByteBuffer);
+ returnToPool(outByteBuffer);
+ returnToPool(state);
}
}
@@ -252,6 +260,28 @@ public class PositionedCryptoInputStream extends CtrCryptoInputStream {
}
}
+ /**
+ * Gets direct buffer from pool. Caller MUST also call {@link #returnToPool(ByteBuffer)}.
+ *
+ * @return the buffer.
+ * @see #returnToPool(ByteBuffer)
+ */
+ private ByteBuffer getBuffer() {
+ ByteBuffer buffer = byteBufferPool.poll();
+ return buffer != null ? buffer : ByteBuffer.allocateDirect(getBufferSize());
+ }
+
+ /**
+ * Gets CryptoCipher from pool. Caller MUST also call {@link #returnToPool(CipherState)}.
+ *
+ * @return the CipherState instance.
+ * @throws IOException if an I/O error occurs.
+ */
+ private CipherState getCipherState() throws IOException {
+ CipherState state = cipherStatePool.poll();
+ return state != null ? state : new CipherState(Utils.getCipherInstance(AES.CTR_NO_PADDING, properties));
+ }
+
/**
* This method is executed immediately after decryption. Check whether
* cipher should be updated and recalculate padding if needed.
@@ -280,68 +310,80 @@ public class PositionedCryptoInputStream extends CtrCryptoInputStream {
}
/**
- * Calculates the counter and iv, reset the cipher.
+ * 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.
*
- * @param state the CipherState instance.
+ * @param buffer the buffer into which the data is read.
+ * @param length the maximum number of bytes to read.
+ * @param offset the start offset in the data.
* @param position the offset from the start of the stream.
- * @param iv the iv.
+ * @throws IOException if an I/O error occurs.
+ * @return int the total number of decrypted data bytes read into the
+ * buffer.
*/
- @SuppressWarnings("resource") // getCryptoCipher does not allocate
- private void resetCipher(final CipherState state, final long position, final byte[] iv) {
- final long counter = getCounter(position);
- CtrCryptoInputStream.calculateIV(getInitIV(), counter, iv);
- try {
- state.getCryptoCipher().init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
- } catch (final GeneralSecurityException e) {
- // Ignore
+ public int read(final long position, final byte[] buffer, final int offset, final 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);
}
- state.reset(false);
+ return n;
}
/**
- * Gets CryptoCipher from pool.
+ * Reads 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.
*
- * @return the CipherState instance.
+ * @param position the offset from the start of the stream.
+ * @param buffer the buffer into which the data is read.
* @throws IOException if an I/O error occurs.
*/
- private CipherState getCipherState() throws IOException {
- CipherState state = cipherPool.poll();
- if (state == null) {
- final CryptoCipher cryptoCipher;
- try {
- cryptoCipher = CryptoCipherFactory.getCryptoCipher(AES.CTR_NO_PADDING, properties);
- } catch (final GeneralSecurityException e) {
- throw new IOException(e);
- }
- state = new CipherState(cryptoCipher);
- }
-
- return state;
+ public void readFully(final long position, final byte[] buffer) throws IOException {
+ readFully(position, buffer, 0, buffer.length);
}
/**
- * Returns CryptoCipher to pool.
+ * Reads 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.
*
- * @param state the CipherState instance.
+ * @param buffer the buffer into which the data is read.
+ * @param length the maximum number of bytes to read.
+ * @param offset the start offset in the data.
+ * @param position the offset from the start of the stream.
+ * @throws IOException if an I/O error occurs.
*/
- private void returnCipherState(final CipherState state) {
- if (state != null) {
- cipherPool.add(state);
+ public void readFully(final long position, final byte[] buffer, final int offset, final 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);
}
}
/**
- * Gets direct buffer from pool.
+ * Calculates the counter and iv, reset the cipher.
*
- * @return the buffer.
+ * @param state the CipherState instance.
+ * @param position the offset from the start of the stream.
+ * @param iv the iv.
*/
- private ByteBuffer getBuffer() {
- ByteBuffer buffer = bufferPool.poll();
- if (buffer == null) {
- buffer = ByteBuffer.allocateDirect(getBufferSize());
+ @SuppressWarnings("resource") // getCryptoCipher does not allocate
+ private void resetCipher(final CipherState state, final long position, final byte[] iv) {
+ final long counter = getCounter(position);
+ CtrCryptoInputStream.calculateIV(getInitIV(), counter, iv);
+ try {
+ state.getCryptoCipher().init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
+ } catch (final GeneralSecurityException e) {
+ // Ignore
}
-
- return buffer;
+ state.reset(false);
}
/**
@@ -349,77 +391,21 @@ public class PositionedCryptoInputStream extends CtrCryptoInputStream {
*
* @param buf the buffer.
*/
- private void returnBuffer(final ByteBuffer buf) {
+ private void returnToPool(final ByteBuffer buf) {
if (buf != null) {
buf.clear();
- bufferPool.add(buf);
+ byteBufferPool.add(buf);
}
}
/**
- * Overrides the {@link CryptoInputStream#close()}. Closes this input stream
- * and releases any system resources associated with the stream.
+ * Returns CryptoCipher to pool.
*
- * @throws IOException if an I/O error occurs.
+ * @param state the CipherState instance.
*/
- @Override
- public void close() throws IOException {
- if (!isOpen()) {
- return;
- }
-
- cleanBufferPool();
- super.close();
- }
-
- /** Cleans direct buffer pool */
- private void cleanBufferPool() {
- ByteBuffer buf;
- while ((buf = bufferPool.poll()) != null) {
- CryptoInputStream.freeDirectBuffer(buf);
- }
- }
-
- private static class CipherState {
-
- private final CryptoCipher cryptoCipher;
- private boolean reset;
-
- /**
- * Constructs a new instance.
- *
- * @param cryptoCipher the CryptoCipher instance.
- */
- public CipherState(final CryptoCipher cryptoCipher) {
- this.cryptoCipher = cryptoCipher;
- this.reset = false;
- }
-
- /**
- * Gets the CryptoCipher instance.
- *
- * @return the cipher.
- */
- public CryptoCipher getCryptoCipher() {
- return cryptoCipher;
- }
-
- /**
- * Gets the reset.
- *
- * @return the value of reset.
- */
- public boolean isReset() {
- return reset;
- }
-
- /**
- * Sets the value of reset.
- *
- * @param reset the reset.
- */
- public void reset(final boolean reset) {
- this.reset = reset;
+ private void returnToPool(final CipherState state) {
+ if (state != null) {
+ cipherStatePool.add(state);
}
}
}
diff --git a/src/main/java/org/apache/commons/crypto/utils/Utils.java b/src/main/java/org/apache/commons/crypto/utils/Utils.java
index 15e7c91..c0d9ec1 100644
--- a/src/main/java/org/apache/commons/crypto/utils/Utils.java
+++ b/src/main/java/org/apache/commons/crypto/utils/Utils.java
@@ -120,9 +120,7 @@ public final class Utils {
* @return the CryptoCipher instance.
* @throws IOException if an I/O error occurs.
*/
- public static CryptoCipher getCipherInstance(
- final String transformation, final Properties properties)
- throws IOException {
+ public static CryptoCipher getCipherInstance(final String transformation, final Properties properties) throws IOException {
try {
return CryptoCipherFactory.getCryptoCipher(transformation, properties);
} catch (final GeneralSecurityException e) {