diff options
author | lloyd <[email protected]> | 2012-01-06 18:43:25 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-01-06 18:43:25 +0000 |
commit | d9796c5610e0deb63cbf0a52d374c3c5e755c7e4 (patch) | |
tree | 0370e28ee1ea5b18f2bf5c4c6b964513c699c101 /src | |
parent | 0e3930065b0ad067b04416d4cf582ad6d9b80a3d (diff) |
In the reader preallocate the buffer that we'll store the computed MAC
into for comparison. This eliminates the last memory allocation in the
record processing layers except of course the elephant that the Pipe
doing the ciphering will copy its input. That's an issue for
Pipe/Filter 2.0 though.
Diffstat (limited to 'src')
-rw-r--r-- | src/tls/rec_read.cpp | 40 | ||||
-rw-r--r-- | src/tls/tls_record.h | 3 |
2 files changed, 22 insertions, 21 deletions
diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp index c2c6309a6..f8e6bab26 100644 --- a/src/tls/rec_read.cpp +++ b/src/tls/rec_read.cpp @@ -27,15 +27,16 @@ Record_Reader::Record_Reader() : */ void Record_Reader::reset() { + m_macbuf.clear(); + + zeroise(m_readbuf); + m_readbuf_pos = 0; + m_cipher.reset(); delete m_mac; m_mac = 0; - zeroise(m_readbuf); - m_readbuf_pos = 0; - - m_mac_size = 0; m_block_size = 0; m_iv_size = 0; m_major = m_minor = 0; @@ -126,7 +127,7 @@ void Record_Reader::activate(const TLS_Cipher_Suite& suite, m_mac = af.make_mac("HMAC(" + mac_algo + ")"); m_mac->set_key(mac_key); - m_mac_size = m_mac->output_length(); + m_macbuf.resize(m_mac->output_length()); } else throw Invalid_Argument("Record_Reader: Unknown hash " + mac_algo); @@ -178,7 +179,7 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, } // Possible SSLv2 format client hello - if(m_mac_size == 0 && (m_readbuf[0] & 0x80) && (m_readbuf[2] == 1)) + if((!m_mac) && (m_readbuf[0] & 0x80) && (m_readbuf[2] == 1)) { if(m_readbuf[3] == 0 && m_readbuf[4] == 2) throw TLS_Exception(PROTOCOL_VERSION, @@ -216,7 +217,8 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, m_readbuf[0] != APPLICATION_DATA) { throw TLS_Exception(UNEXPECTED_MESSAGE, - "Record_Reader: Unknown record type"); + "Unknown record type " + to_string(m_readbuf[0]) + + " from counterparty"); } const u16bit version = make_u16bit(m_readbuf[1], m_readbuf[2]); @@ -224,7 +226,7 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, if(m_major && (m_readbuf[1] != m_major || m_readbuf[2] != m_minor)) throw TLS_Exception(PROTOCOL_VERSION, - "Record_Reader: Got unexpected version"); + "Got unexpected version from counterparty"); if(record_len > MAX_CIPHERTEXT_SIZE) throw TLS_Exception(RECORD_OVERFLOW, @@ -239,7 +241,7 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, "Have the full record"); // Null mac means no encryption either, only valid during handshake - if(m_mac_size == 0) + if(!m_mac) { if(m_readbuf[0] != CHANGE_CIPHER_SPEC && m_readbuf[0] != ALERT && @@ -299,10 +301,12 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, } } - if(record_len < m_mac_size + pad_size + m_iv_size) - throw Decoding_Error("Record_Reader: Record truncated"); + const size_t mac_pad_iv_size = m_macbuf.size() + pad_size + m_iv_size; - const u16bit plain_length = record_len - (m_mac_size + pad_size + m_iv_size); + if(record_len < mac_pad_iv_size) + throw Decoding_Error("Record sent with invalid length"); + + const u16bit plain_length = record_len - mac_pad_iv_size; if(plain_length > m_max_fragment) throw TLS_Exception(RECORD_OVERFLOW, "Plaintext record is too large"); @@ -319,16 +323,12 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, ++m_seq_no; - MemoryVector<byte> computed_mac = m_mac->final(); - - if(computed_mac.size() != m_mac_size) - throw TLS_Exception(INTERNAL_ERROR, - "MAC produced value of unexpected size"); + m_mac->final(m_macbuf); - const size_t mac_offset = record_len - (m_mac_size + pad_size); + const size_t mac_offset = record_len - (m_macbuf.size() + pad_size); - if(!same_mem(&m_readbuf[TLS_HEADER_SIZE + mac_offset], &computed_mac[0], m_mac_size)) - throw TLS_Exception(BAD_RECORD_MAC, "Record_Reader: MAC failure"); + if(!same_mem(&m_readbuf[TLS_HEADER_SIZE + mac_offset], &m_macbuf[0], m_macbuf.size())) + throw TLS_Exception(BAD_RECORD_MAC, "Message authentication failure"); msg_type = m_readbuf[0]; diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h index 9428474b3..c7d2d0018 100644 --- a/src/tls/tls_record.h +++ b/src/tls/tls_record.h @@ -120,11 +120,12 @@ class BOTAN_DLL Record_Reader size_t desired); MemoryVector<byte> m_readbuf; + MemoryVector<byte> m_macbuf; size_t m_readbuf_pos; Pipe m_cipher; MessageAuthenticationCode* m_mac; - size_t m_block_size, m_mac_size, m_iv_size, m_max_fragment; + size_t m_block_size, m_iv_size, m_max_fragment; u64bit m_seq_no; byte m_major, m_minor; }; |