Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java')
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java477
1 files changed, 0 insertions, 477 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java b/core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java
deleted file mode 100644
index b06d1f53..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java
+++ /dev/null
@@ -1,477 +0,0 @@
-package org.bouncycastle.crypto.io;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.bouncycastle.crypto.BufferedBlockCipher;
-import org.bouncycastle.crypto.InvalidCipherTextException;
-import org.bouncycastle.crypto.SkippingCipher;
-import org.bouncycastle.crypto.StreamCipher;
-import org.bouncycastle.crypto.modes.AEADBlockCipher;
-import org.bouncycastle.util.Arrays;
-
-/**
- * A CipherInputStream is composed of an InputStream and a cipher so that read() methods return data
- * that are read in from the underlying InputStream but have been additionally processed by the
- * Cipher. The cipher must be fully initialized before being used by a CipherInputStream.
- * <p>
- * For example, if the Cipher is initialized for decryption, the
- * CipherInputStream will attempt to read in data and decrypt them,
- * before returning the decrypted data.
- */
-public class CipherInputStream
- extends FilterInputStream
-{
- private static final int INPUT_BUF_SIZE = 2048;
-
- private SkippingCipher skippingCipher;
- private byte[] inBuf;
-
- private BufferedBlockCipher bufferedBlockCipher;
- private StreamCipher streamCipher;
- private AEADBlockCipher aeadBlockCipher;
-
- private byte[] buf;
- private byte[] markBuf;
-
-
- private int bufOff;
- private int maxBuf;
- private boolean finalized;
- private long markPosition;
- private int markBufOff;
-
- /**
- * Constructs a CipherInputStream from an InputStream and a
- * BufferedBlockCipher.
- */
- public CipherInputStream(
- InputStream is,
- BufferedBlockCipher cipher)
- {
- this(is, cipher, INPUT_BUF_SIZE);
- }
-
- /**
- * Constructs a CipherInputStream from an InputStream and a StreamCipher.
- */
- public CipherInputStream(
- InputStream is,
- StreamCipher cipher)
- {
- this(is, cipher, INPUT_BUF_SIZE);
- }
-
- /**
- * Constructs a CipherInputStream from an InputStream and an AEADBlockCipher.
- */
- public CipherInputStream(
- InputStream is,
- AEADBlockCipher cipher)
- {
- this(is, cipher, INPUT_BUF_SIZE);
- }
-
- /**
- * Constructs a CipherInputStream from an InputStream, a
- * BufferedBlockCipher, and a specified internal buffer size.
- */
- public CipherInputStream(
- InputStream is,
- BufferedBlockCipher cipher,
- int bufSize)
- {
- super(is);
-
- this.bufferedBlockCipher = cipher;
- this.inBuf = new byte[bufSize];
- this.skippingCipher = (cipher instanceof SkippingCipher) ? (SkippingCipher)cipher : null;
- }
-
- /**
- * Constructs a CipherInputStream from an InputStream, a StreamCipher, and a specified internal buffer size.
- */
- public CipherInputStream(
- InputStream is,
- StreamCipher cipher,
- int bufSize)
- {
- super(is);
-
- this.streamCipher = cipher;
- this.inBuf = new byte[bufSize];
- this.skippingCipher = (cipher instanceof SkippingCipher) ? (SkippingCipher)cipher : null;
- }
-
- /**
- * Constructs a CipherInputStream from an InputStream, an AEADBlockCipher, and a specified internal buffer size.
- */
- public CipherInputStream(
- InputStream is,
- AEADBlockCipher cipher,
- int bufSize)
- {
- super(is);
-
- this.aeadBlockCipher = cipher;
- this.inBuf = new byte[bufSize];
- this.skippingCipher = (cipher instanceof SkippingCipher) ? (SkippingCipher)cipher : null;
- }
-
- /**
- * Read data from underlying stream and process with cipher until end of stream or some data is
- * available after cipher processing.
- *
- * @return -1 to indicate end of stream, or the number of bytes (> 0) available.
- */
- private int nextChunk()
- throws IOException
- {
- if (finalized)
- {
- return -1;
- }
-
- bufOff = 0;
- maxBuf = 0;
-
- // Keep reading until EOF or cipher processing produces data
- while (maxBuf == 0)
- {
- int read = in.read(inBuf);
- if (read == -1)
- {
- finaliseCipher();
- if (maxBuf == 0)
- {
- return -1;
- }
- return maxBuf;
- }
-
- try
- {
- ensureCapacity(read, false);
- if (bufferedBlockCipher != null)
- {
- maxBuf = bufferedBlockCipher.processBytes(inBuf, 0, read, buf, 0);
- }
- else if (aeadBlockCipher != null)
- {
- maxBuf = aeadBlockCipher.processBytes(inBuf, 0, read, buf, 0);
- }
- else
- {
- streamCipher.processBytes(inBuf, 0, read, buf, 0);
- maxBuf = read;
- }
- }
- catch (Exception e)
- {
- throw new CipherIOException("Error processing stream ", e);
- }
- }
- return maxBuf;
- }
-
- private void finaliseCipher()
- throws IOException
- {
- try
- {
- finalized = true;
- ensureCapacity(0, true);
- if (bufferedBlockCipher != null)
- {
- maxBuf = bufferedBlockCipher.doFinal(buf, 0);
- }
- else if (aeadBlockCipher != null)
- {
- maxBuf = aeadBlockCipher.doFinal(buf, 0);
- }
- else
- {
- maxBuf = 0; // a stream cipher
- }
- }
- catch (final InvalidCipherTextException e)
- {
- throw new InvalidCipherTextIOException("Error finalising cipher", e);
- }
- catch (Exception e)
- {
- throw new IOException("Error finalising cipher " + e);
- }
- }
-
- /**
- * Reads data from the underlying stream and processes it with the cipher until the cipher
- * outputs data, and returns the next available byte.
- * <p>
- * If the underlying stream is exhausted by this call, the cipher will be finalised.
- * </p>
- * @throws IOException if there was an error closing the input stream.
- * @throws InvalidCipherTextIOException if the data read from the stream was invalid ciphertext
- * (e.g. the cipher is an AEAD cipher and the ciphertext tag check fails).
- */
- public int read()
- throws IOException
- {
- if (bufOff >= maxBuf)
- {
- if (nextChunk() < 0)
- {
- return -1;
- }
- }
-
- return buf[bufOff++] & 0xff;
- }
-
- /**
- * Reads data from the underlying stream and processes it with the cipher until the cipher
- * outputs data, and then returns up to <code>b.length</code> bytes in the provided array.
- * <p>
- * If the underlying stream is exhausted by this call, the cipher will be finalised.
- * </p>
- * @param b the buffer into which the data is 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 there was an error closing the input stream.
- * @throws InvalidCipherTextIOException if the data read from the stream was invalid ciphertext
- * (e.g. the cipher is an AEAD cipher and the ciphertext tag check fails).
- */
- public int read(
- byte[] b)
- throws IOException
- {
- return read(b, 0, b.length);
- }
-
- /**
- * Reads data from the underlying stream and processes it with the cipher until the cipher
- * outputs data, and then returns up to <code>len</code> bytes in the provided array.
- * <p>
- * If the underlying stream is exhausted by this call, the cipher will be finalised.
- * </p>
- * @param b the buffer into which the data is read.
- * @param off the start offset in the destination array <code>b</code>
- * @param len the maximum number of bytes 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 there was an error closing the input stream.
- * @throws InvalidCipherTextIOException if the data read from the stream was invalid ciphertext
- * (e.g. the cipher is an AEAD cipher and the ciphertext tag check fails).
- */
- public int read(
- byte[] b,
- int off,
- int len)
- throws IOException
- {
- if (bufOff >= maxBuf)
- {
- if (nextChunk() < 0)
- {
- return -1;
- }
- }
-
- int toSupply = Math.min(len, available());
- System.arraycopy(buf, bufOff, b, off, toSupply);
- bufOff += toSupply;
- return toSupply;
- }
-
- public long skip(
- long n)
- throws IOException
- {
- if (n <= 0)
- {
- return 0;
- }
-
- if (skippingCipher != null)
- {
- int avail = available();
- if (n <= avail)
- {
- bufOff += n;
-
- return n;
- }
-
- bufOff = maxBuf;
-
- long skip = in.skip(n - avail);
-
- long cSkip = skippingCipher.skip(skip);
-
- if (skip != cSkip)
- {
- throw new IOException("Unable to skip cipher " + skip + " bytes.");
- }
-
- return skip + avail;
- }
- else
- {
- int skip = (int)Math.min(n, available());
- bufOff += skip;
-
- return skip;
- }
- }
-
- public int available()
- throws IOException
- {
- return maxBuf - bufOff;
- }
-
- /**
- * Ensure the cipher text buffer has space sufficient to accept an upcoming output.
- *
- * @param updateSize the size of the pending update.
- * @param finalOutput <code>true</code> iff this the cipher is to be finalised.
- */
- private void ensureCapacity(int updateSize, boolean finalOutput)
- {
- int bufLen = updateSize;
- if (finalOutput)
- {
- if (bufferedBlockCipher != null)
- {
- bufLen = bufferedBlockCipher.getOutputSize(updateSize);
- }
- else if (aeadBlockCipher != null)
- {
- bufLen = aeadBlockCipher.getOutputSize(updateSize);
- }
- }
- else
- {
- if (bufferedBlockCipher != null)
- {
- bufLen = bufferedBlockCipher.getUpdateOutputSize(updateSize);
- }
- else if (aeadBlockCipher != null)
- {
- bufLen = aeadBlockCipher.getUpdateOutputSize(updateSize);
- }
- }
-
- if ((buf == null) || (buf.length < bufLen))
- {
- buf = new byte[bufLen];
- }
- }
-
- /**
- * Closes the underlying input stream and finalises the processing of the data by the cipher.
- *
- * @throws IOException if there was an error closing the input stream.
- * @throws InvalidCipherTextIOException if the data read from the stream was invalid ciphertext
- * (e.g. the cipher is an AEAD cipher and the ciphertext tag check fails).
- */
- public void close()
- throws IOException
- {
- try
- {
- in.close();
- }
- finally
- {
- if (!finalized)
- {
- // Reset the cipher, discarding any data buffered in it
- // Errors in cipher finalisation trump I/O error closing input
- finaliseCipher();
- }
- }
- maxBuf = bufOff = 0;
- markBufOff = 0;
- markPosition = 0;
- if (markBuf != null)
- {
- Arrays.fill(markBuf, (byte)0);
- markBuf = null;
- }
- if (buf != null)
- {
- Arrays.fill(buf, (byte)0);
- buf = null;
- }
- Arrays.fill(inBuf, (byte)0);
- }
-
- /**
- * Mark the current position.
- * <p>
- * This method only works if markSupported() returns true - which means the underlying stream supports marking, and the cipher passed
- * in to this stream's constructor is a SkippingCipher (so capable of being reset to an arbitrary point easily).
- * </p>
- * @param readlimit the maximum read ahead required before a reset() may be called.
- */
- public void mark(int readlimit)
- {
- in.mark(readlimit);
- if (skippingCipher != null)
- {
- markPosition = skippingCipher.getPosition();
- }
-
- if (buf != null)
- {
- markBuf = new byte[buf.length];
- System.arraycopy(buf, 0, markBuf, 0, buf.length);
- }
-
- markBufOff = bufOff;
- }
-
- /**
- * Reset to the last marked position, if supported.
- *
- * @throws IOException if marking not supported by the cipher used, or the underlying stream.
- */
- public void reset()
- throws IOException
- {
- if (skippingCipher == null)
- {
- throw new IOException("cipher must implement SkippingCipher to be used with reset()");
- }
-
- in.reset();
-
- skippingCipher.seekTo(markPosition);
-
- if (markBuf != null)
- {
- buf = markBuf;
- }
-
- bufOff = markBufOff;
- }
-
- /**
- * Return true if mark(readlimit) is supported. This will be true if the underlying stream supports marking and the
- * cipher used is a SkippingCipher,
- *
- * @return true if mark(readlimit) supported, false otherwise.
- */
- public boolean markSupported()
- {
- if (skippingCipher != null)
- {
- return in.markSupported();
- }
-
- return false;
- }
-
-}