aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-08-08 22:22:09 +0000
committerlloyd <[email protected]>2012-08-08 22:22:09 +0000
commitd2afa9cea20209da929f20f49e27e31f4d6fa68b (patch)
treea6a5150712f69c81d5e4b414e4969ac465f84e3e /src
parentc76913f15bdd5699b02f6d68af9044b1a8219acf (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.cpp56
-rw-r--r--src/tls/tls_handshake_io.h3
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;