aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/BufferedAsymmetricBlockCipher.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/BufferedAsymmetricBlockCipher.java')
-rw-r--r--libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/BufferedAsymmetricBlockCipher.java171
1 files changed, 171 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/BufferedAsymmetricBlockCipher.java b/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/BufferedAsymmetricBlockCipher.java
new file mode 100644
index 000000000..9cefae149
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/BufferedAsymmetricBlockCipher.java
@@ -0,0 +1,171 @@
+package org.spongycastle.crypto;
+
+/**
+ * a buffer wrapper for an asymmetric block cipher, allowing input
+ * to be accumulated in a piecemeal fashion until final processing.
+ */
+public class BufferedAsymmetricBlockCipher
+{
+ protected byte[] buf;
+ protected int bufOff;
+
+ private final AsymmetricBlockCipher cipher;
+
+ /**
+ * base constructor.
+ *
+ * @param cipher the cipher this buffering object wraps.
+ */
+ public BufferedAsymmetricBlockCipher(
+ AsymmetricBlockCipher cipher)
+ {
+ this.cipher = cipher;
+ }
+
+ /**
+ * return the underlying cipher for the buffer.
+ *
+ * @return the underlying cipher for the buffer.
+ */
+ public AsymmetricBlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ /**
+ * return the amount of data sitting in the buffer.
+ *
+ * @return the amount of data sitting in the buffer.
+ */
+ public int getBufferPosition()
+ {
+ return bufOff;
+ }
+
+ /**
+ * initialise the buffer and the underlying cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params)
+ {
+ reset();
+
+ cipher.init(forEncryption, params);
+
+ //
+ // we allow for an extra byte where people are using their own padding
+ // mechanisms on a raw cipher.
+ //
+ buf = new byte[cipher.getInputBlockSize() + (forEncryption ? 1 : 0)];
+ bufOff = 0;
+ }
+
+ /**
+ * returns the largest size an input block can be.
+ *
+ * @return maximum size for an input block.
+ */
+ public int getInputBlockSize()
+ {
+ return cipher.getInputBlockSize();
+ }
+
+ /**
+ * returns the maximum size of the block produced by this cipher.
+ *
+ * @return maximum size of the output block produced by the cipher.
+ */
+ public int getOutputBlockSize()
+ {
+ return cipher.getOutputBlockSize();
+ }
+
+ /**
+ * add another byte for processing.
+ *
+ * @param in the input byte.
+ */
+ public void processByte(
+ byte in)
+ {
+ if (bufOff >= buf.length)
+ {
+ throw new DataLengthException("attempt to process message too long for cipher");
+ }
+
+ buf[bufOff++] = in;
+ }
+
+ /**
+ * add len bytes to the buffer for processing.
+ *
+ * @param in the input data
+ * @param inOff offset into the in array where the data starts
+ * @param len the length of the block to be processed.
+ */
+ public void processBytes(
+ byte[] in,
+ int inOff,
+ int len)
+ {
+ if (len == 0)
+ {
+ return;
+ }
+
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Can't have a negative input length!");
+ }
+
+ if (bufOff + len > buf.length)
+ {
+ throw new DataLengthException("attempt to process message too long for cipher");
+ }
+
+ System.arraycopy(in, inOff, buf, bufOff, len);
+ bufOff += len;
+ }
+
+ /**
+ * process the contents of the buffer using the underlying
+ * cipher.
+ *
+ * @return the result of the encryption/decryption process on the
+ * buffer.
+ * @exception InvalidCipherTextException if we are given a garbage block.
+ */
+ public byte[] doFinal()
+ throws InvalidCipherTextException
+ {
+ byte[] out = cipher.processBlock(buf, 0, bufOff);
+
+ reset();
+
+ return out;
+ }
+
+ /**
+ * Reset the buffer and the underlying cipher.
+ */
+ public void reset()
+ {
+ /*
+ * clean the buffer.
+ */
+ if (buf != null)
+ {
+ for (int i = 0; i < buf.length; i++)
+ {
+ buf[i] = 0;
+ }
+ }
+
+ bufOff = 0;
+ }
+}