diff options
-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; }; |