diff options
author | lloyd <[email protected]> | 2012-08-08 22:22:09 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-08-08 22:22:09 +0000 |
commit | d2afa9cea20209da929f20f49e27e31f4d6fa68b (patch) | |
tree | a6a5150712f69c81d5e4b414e4969ac465f84e3e /src | |
parent | c76913f15bdd5699b02f6d68af9044b1a8219acf (diff) |
We weren't handling DTLS handshake fragments at all. Now reject them
while continuing to work with unfragmented records and add the
framework for defragmentation.
Diffstat (limited to 'src')
-rw-r--r-- | src/tls/tls_handshake_io.cpp | 56 | ||||
-rw-r--r-- | src/tls/tls_handshake_io.h | 3 |
2 files changed, 35 insertions, 24 deletions
diff --git a/src/tls/tls_handshake_io.cpp b/src/tls/tls_handshake_io.cpp index fb56f56bd..abc2f49f7 100644 --- a/src/tls/tls_handshake_io.cpp +++ b/src/tls/tls_handshake_io.cpp @@ -145,15 +145,15 @@ void Datagram_Handshake_IO::add_input(const byte rec_type, if(record_size < total_size) throw Decoding_Error("Bad lengths in DTLS header"); - if(message_seq < m_in_message_seq) - return; - - m_messages[message_seq].add_fragment(&record[DTLS_HANDSHAKE_HEADER_LEN], - fragment_length, - fragment_offset, - epoch, - msg_type, - msg_len); + if(message_seq >= m_in_message_seq) + { + m_messages[message_seq].add_fragment(&record[DTLS_HANDSHAKE_HEADER_LEN], + fragment_length, + fragment_offset, + epoch, + msg_type, + msg_len); + } record += total_size; record_size -= total_size; @@ -194,32 +194,44 @@ void Datagram_Handshake_IO::Handshake_Reassembly::add_fragment( byte msg_type, size_t msg_length) { + if(complete()) + return; // already have entire message, ignore this + if(m_msg_type == HANDSHAKE_NONE) { + m_epoch = epoch; m_msg_type = msg_type; m_msg_length = msg_length; -#warning DoS should resize as inputs are added (?) - m_buffer.resize(m_msg_length); - m_epoch = epoch; } + if(msg_type != m_msg_type || msg_length != m_msg_length || epoch != m_epoch) + throw Decoding_Error("Inconsistent values in DTLS handshake header"); + if(fragment_offset > m_msg_length) - throw Decoding_Error("Fragment offset greater than message length"); + throw Decoding_Error("Fragment offset past end of message"); if(fragment_offset + fragment_length > m_msg_length) - throw Decoding_Error("Fragment passes end of message"); + throw Decoding_Error("Fragment overlaps past end of message"); - if(msg_type != m_msg_type || - msg_length != m_msg_length || - epoch != m_epoch) - throw Decoding_Error("Datagram_Handshake_IO - inconsistent values"); + if(fragment_offset == 0 && fragment_length == m_msg_length) + { + m_fragments.clear(); + m_message.assign(fragment, fragment+fragment_length); + } + else + { + throw Internal_Error("Defragmentation not implemented"); - copy_mem(&m_buffer[fragment_offset], fragment, fragment_length); + m_fragments[fragment_offset] = + std::deque<byte>(fragment, fragment+fragment_length); + + auto range = m_fragments.equal_range(fragment_offset); + } } bool Datagram_Handshake_IO::Handshake_Reassembly::complete() const { - return true; // FIXME + return (m_msg_type != HANDSHAKE_NONE && m_message.size() == m_msg_length); } std::pair<Handshake_Type, std::vector<byte>> @@ -228,9 +240,7 @@ Datagram_Handshake_IO::Handshake_Reassembly::message() const if(!complete()) throw Internal_Error("Datagram_Handshake_IO - message not complete"); - auto msg = std::make_pair(static_cast<Handshake_Type>(m_msg_type), m_buffer); - - return msg; + return std::make_pair(static_cast<Handshake_Type>(m_msg_type), m_message); } std::vector<byte> diff --git a/src/tls/tls_handshake_io.h b/src/tls/tls_handshake_io.h index ca23de264..7628126d6 100644 --- a/src/tls/tls_handshake_io.h +++ b/src/tls/tls_handshake_io.h @@ -135,7 +135,8 @@ class Datagram_Handshake_IO : public Handshake_IO size_t m_msg_length = 0; u16bit m_epoch = 0; - std::vector<byte> m_buffer; + std::map<size_t, std::deque<byte>> m_fragments; + std::vector<byte> m_message; }; std::map<u16bit, Handshake_Reassembly> m_messages; |