diff options
author | David Hook <dgh@cryptoworkshop.com> | 2013-05-31 11:07:45 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2013-05-31 11:07:45 +0400 |
commit | 2b976f5364cfdbc37d3086019d93483c983eb80b (patch) | |
tree | cb846af3fd1d43f9c2562a1fb2d06b997ad8f229 /core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java | |
parent | 5f714bd92fbd780d22406f4bc3681be005f6f04a (diff) |
initial reshuffle
Diffstat (limited to 'core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java')
-rw-r--r-- | core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java new file mode 100644 index 00000000..d5b2b98e --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java @@ -0,0 +1,127 @@ +package org.bouncycastle.crypto.tls; + +import java.io.IOException; + +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.util.Arrays; + +/** + * A NULL CipherSuite with optional MAC + */ +public class TlsNullCipher + implements TlsCipher +{ + protected TlsContext context; + + protected TlsMac writeMac; + protected TlsMac readMac; + + public TlsNullCipher(TlsContext context) + { + this.context = context; + this.writeMac = null; + this.readMac = null; + } + + public TlsNullCipher(TlsContext context, Digest clientWriteDigest, Digest serverWriteDigest) + throws IOException + { + + if ((clientWriteDigest == null) != (serverWriteDigest == null)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + this.context = context; + + TlsMac clientWriteMac = null, serverWriteMac = null; + + if (clientWriteDigest != null) + { + + int key_block_size = clientWriteDigest.getDigestSize() + + serverWriteDigest.getDigestSize(); + byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); + + int offset = 0; + + clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, + clientWriteDigest.getDigestSize()); + offset += clientWriteDigest.getDigestSize(); + + serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, + serverWriteDigest.getDigestSize()); + offset += serverWriteDigest.getDigestSize(); + + if (offset != key_block_size) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + if (context.isServer()) + { + writeMac = serverWriteMac; + readMac = clientWriteMac; + } + else + { + writeMac = clientWriteMac; + readMac = serverWriteMac; + } + } + + public int getPlaintextLimit(int ciphertextLimit) + { + int result = ciphertextLimit; + if (writeMac != null) + { + result -= writeMac.getSize(); + } + return result; + } + + public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) + throws IOException + { + + if (writeMac == null) + { + return Arrays.copyOfRange(plaintext, offset, offset + len); + } + + byte[] mac = writeMac.calculateMac(seqNo, type, plaintext, offset, len); + byte[] ciphertext = new byte[len + mac.length]; + System.arraycopy(plaintext, offset, ciphertext, 0, len); + System.arraycopy(mac, 0, ciphertext, len, mac.length); + return ciphertext; + } + + public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) + throws IOException + { + + if (readMac == null) + { + return Arrays.copyOfRange(ciphertext, offset, offset + len); + } + + int macSize = readMac.getSize(); + if (len < macSize) + { + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + int macInputLen = len - macSize; + + byte[] receivedMac = Arrays.copyOfRange(ciphertext, offset + macInputLen, offset + len); + byte[] computedMac = readMac.calculateMac(seqNo, type, ciphertext, offset, macInputLen); + + if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) + { + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + } + + return Arrays.copyOfRange(ciphertext, offset, offset + macInputLen); + } +} |