aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-09-12 13:57:48 +0000
committerlloyd <[email protected]>2012-09-12 13:57:48 +0000
commitbd209a05a784f74bdeb38a7c93c9ce57977453a0 (patch)
tree861a35e740696417b306484ee759c3e1542ade75
parent0ed49ddb3090777fad5627b585de407c472725bd (diff)
CBC overwrote (encrypted) the following block in write_record. I
missed it before because the buffer was pre-sized to maximum allowable, thus it just encrypted something we never sent. However after the buffer sizes were set to zero, it would start encrypting ... something ... after the block. This would manifest by strange crashes during a full client renegotiation. The problem was that the buffer was sized up a bit for sending the unencrypted messages (client kex, etc) and so we had some wiggle room. However sending an encrypted client kex took more space than that (due to the MAC, etc) so a full renegotiation would cause values to be overwritten.
-rw-r--r--src/tls/tls_record.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/tls/tls_record.cpp b/src/tls/tls_record.cpp
index 23b44e67e..d0bc8bc69 100644
--- a/src/tls/tls_record.cpp
+++ b/src/tls/tls_record.cpp
@@ -160,6 +160,9 @@ void write_record(std::vector<byte>& output,
if(buf_size > MAX_CIPHERTEXT_SIZE)
throw Internal_Error("Produced ciphertext larger than protocol allows");
+ BOTAN_ASSERT(buf_size + header_size == output.size(),
+ "Output buffer is sized properly");
+
if(StreamCipher* sc = cipherstate->stream_cipher())
{
sc->cipher1(&output[header_size], buf_size);
@@ -178,7 +181,7 @@ void write_record(std::vector<byte>& output,
xor_buf(&buf[0], &cbc_state[0], block_size);
bc->encrypt(&buf[0]);
- for(size_t i = 1; i <= blocks; ++i)
+ for(size_t i = 1; i < blocks; ++i)
{
xor_buf(&buf[block_size*i], &buf[block_size*(i-1)], block_size);
bc->encrypt(&buf[block_size*i]);