diff options
author | lloyd <[email protected]> | 2012-09-12 13:57:48 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-09-12 13:57:48 +0000 |
commit | bd209a05a784f74bdeb38a7c93c9ce57977453a0 (patch) | |
tree | 861a35e740696417b306484ee759c3e1542ade75 | |
parent | 0ed49ddb3090777fad5627b585de407c472725bd (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.cpp | 5 |
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]); |