diff options
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto')
3 files changed, 73 insertions, 2 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java index 54e54cec..1ba5ebb1 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java @@ -37,6 +37,7 @@ public class GCMBlockCipher // These fields are set by init and not modified by processing private boolean forEncryption; + private boolean initialised; private int macSize; private byte[] lastKey; private byte[] nonce; @@ -99,6 +100,7 @@ public class GCMBlockCipher { this.forEncryption = forEncryption; this.macBlock = null; + this.initialised = true; KeyParameter keyParam; byte[] newNonce = null; @@ -260,6 +262,7 @@ public class GCMBlockCipher public void processAADByte(byte in) { + checkStatus(); // BEGIN android-added if (getTotalInputSizeAfterNewInput(1) > MAX_INPUT_SIZE) { throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes"); @@ -319,11 +322,13 @@ public class GCMBlockCipher public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { + checkStatus(); // BEGIN android-added if (getTotalInputSizeAfterNewInput(1) > MAX_INPUT_SIZE) { throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes"); } // END android-added + bufBlock[bufOff] = in; if (++bufOff == bufBlock.length) { @@ -336,11 +341,13 @@ public class GCMBlockCipher public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { + checkStatus(); // BEGIN android-added if (getTotalInputSizeAfterNewInput(len) > MAX_INPUT_SIZE) { throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes"); } // END android-added + if (in.length < (inOff + len)) { throw new DataLengthException("Input buffer too short"); @@ -385,6 +392,8 @@ public class GCMBlockCipher public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException { + checkStatus(); + if (totalLength == 0) { initCipher(); @@ -534,9 +543,16 @@ public class GCMBlockCipher macBlock = null; } - if (initialAssociatedText != null) + if (forEncryption) { - processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); + initialised = false; + } + else + { + if (initialAssociatedText != null) + { + processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); + } } } @@ -604,4 +620,16 @@ public class GCMBlockCipher cipher.processBlock(counter, 0, tmp, 0); return tmp; } + + private void checkStatus() + { + if (!initialised) + { + if (forEncryption) + { + throw new IllegalStateException("GCM cipher cannot be reused for encryption"); + } + throw new IllegalStateException("GCM cipher needs to be initialised"); + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithID.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithID.java new file mode 100644 index 00000000..e942a5a8 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithID.java @@ -0,0 +1,28 @@ +package org.bouncycastle.crypto.params; + +import org.bouncycastle.crypto.CipherParameters; + +public class ParametersWithID + implements CipherParameters +{ + private CipherParameters parameters; + private byte[] id; + + public ParametersWithID( + CipherParameters parameters, + byte[] id) + { + this.parameters = parameters; + this.id = id; + } + + public byte[] getID() + { + return id; + } + + public CipherParameters getParameters() + { + return parameters; + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java b/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java new file mode 100644 index 00000000..a5c583b0 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java @@ -0,0 +1,15 @@ +package org.bouncycastle.crypto.tls; + +import java.io.EOFException; + +/** + * This exception will be thrown (only) when the connection is closed by the peer without sending a + * {@link AlertDescription#close_notify close_notify} warning alert. If this happens, the TLS + * protocol cannot rule out truncation of the connection data (potentially malicious). It may be + * possible to check for truncation via some property of a higher level protocol built upon TLS, + * e.g. the Content-Length header for HTTPS. + */ +public class TlsNoCloseNotifyException + extends EOFException +{ +} |