Botan  1.11.15
src/lib/tls/tls_handshake_io.h
Go to the documentation of this file.
00001 /*
00002 * TLS Handshake Serialization
00003 * (C) 2012,2014 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #ifndef BOTAN_TLS_HANDSHAKE_IO_H__
00009 #define BOTAN_TLS_HANDSHAKE_IO_H__
00010 
00011 #include <botan/tls_magic.h>
00012 #include <botan/tls_version.h>
00013 #include <botan/loadstor.h>
00014 #include <functional>
00015 #include <vector>
00016 #include <deque>
00017 #include <map>
00018 #include <set>
00019 #include <utility>
00020 
00021 namespace Botan {
00022 
00023 namespace TLS {
00024 
00025 class Handshake_Message;
00026 
00027 /**
00028 * Handshake IO Interface
00029 */
00030 class Handshake_IO
00031    {
00032    public:
00033       virtual Protocol_Version initial_record_version() const = 0;
00034 
00035       virtual std::vector<byte> send(const Handshake_Message& msg) = 0;
00036 
00037       virtual bool timeout_check() = 0;
00038 
00039       virtual std::vector<byte> format(
00040          const std::vector<byte>& handshake_msg,
00041          Handshake_Type handshake_type) const = 0;
00042 
00043       virtual void add_record(const std::vector<byte>& record,
00044                               Record_Type type,
00045                               u64bit sequence_number) = 0;
00046 
00047       /**
00048       * Returns (HANDSHAKE_NONE, std::vector<>()) if no message currently available
00049       */
00050       virtual std::pair<Handshake_Type, std::vector<byte>>
00051          get_next_record(bool expecting_ccs) = 0;
00052 
00053       Handshake_IO() {}
00054 
00055       Handshake_IO(const Handshake_IO&) = delete;
00056 
00057       Handshake_IO& operator=(const Handshake_IO&) = delete;
00058 
00059       virtual ~Handshake_IO() {}
00060    };
00061 
00062 /**
00063 * Handshake IO for stream-based handshakes
00064 */
00065 class Stream_Handshake_IO : public Handshake_IO
00066    {
00067    public:
00068       typedef std::function<void (byte, const std::vector<byte>&)> writer_fn;
00069 
00070       Stream_Handshake_IO(writer_fn writer) : m_send_hs(writer) {}
00071 
00072       Protocol_Version initial_record_version() const override;
00073 
00074       bool timeout_check() override { return false; }
00075 
00076       std::vector<byte> send(const Handshake_Message& msg) override;
00077 
00078       std::vector<byte> format(
00079          const std::vector<byte>& handshake_msg,
00080          Handshake_Type handshake_type) const override;
00081 
00082       void add_record(const std::vector<byte>& record,
00083                       Record_Type type,
00084                       u64bit sequence_number) override;
00085 
00086       std::pair<Handshake_Type, std::vector<byte>>
00087          get_next_record(bool expecting_ccs) override;
00088    private:
00089       std::deque<byte> m_queue;
00090       writer_fn m_send_hs;
00091    };
00092 
00093 /**
00094 * Handshake IO for datagram-based handshakes
00095 */
00096 class Datagram_Handshake_IO : public Handshake_IO
00097    {
00098    public:
00099       typedef std::function<void (u16bit, byte, const std::vector<byte>&)> writer_fn;
00100 
00101       Datagram_Handshake_IO(writer_fn writer,
00102                             class Connection_Sequence_Numbers& seq,
00103                             u16bit mtu) :
00104          m_seqs(seq), m_flights(1), m_send_hs(writer), m_mtu(mtu) {}
00105 
00106       Protocol_Version initial_record_version() const override;
00107 
00108       bool timeout_check() override;
00109 
00110       std::vector<byte> send(const Handshake_Message& msg) override;
00111 
00112       std::vector<byte> format(
00113          const std::vector<byte>& handshake_msg,
00114          Handshake_Type handshake_type) const override;
00115 
00116       void add_record(const std::vector<byte>& record,
00117                       Record_Type type,
00118                       u64bit sequence_number) override;
00119 
00120       std::pair<Handshake_Type, std::vector<byte>>
00121          get_next_record(bool expecting_ccs) override;
00122    private:
00123       std::vector<byte> format_fragment(
00124          const byte fragment[],
00125          size_t fragment_len,
00126          u16bit frag_offset,
00127          u16bit msg_len,
00128          Handshake_Type type,
00129          u16bit msg_sequence) const;
00130 
00131       std::vector<byte> format_w_seq(
00132          const std::vector<byte>& handshake_msg,
00133          Handshake_Type handshake_type,
00134          u16bit msg_sequence) const;
00135 
00136       std::vector<byte> send_message(u16bit msg_seq, u16bit epoch,
00137                                      Handshake_Type msg_type,
00138                                      const std::vector<byte>& msg);
00139 
00140       class Handshake_Reassembly
00141          {
00142          public:
00143             void add_fragment(const byte fragment[],
00144                               size_t fragment_length,
00145                               size_t fragment_offset,
00146                               u16bit epoch,
00147                               byte msg_type,
00148                               size_t msg_length);
00149 
00150             bool complete() const;
00151 
00152             u16bit epoch() const { return m_epoch; }
00153 
00154             std::pair<Handshake_Type, std::vector<byte>> message() const;
00155          private:
00156             byte m_msg_type = HANDSHAKE_NONE;
00157             size_t m_msg_length = 0;
00158             u16bit m_epoch = 0;
00159 
00160             // vector<bool> m_seen;
00161             // vector<byte> m_fragments
00162             std::map<size_t, byte> m_fragments;
00163             std::vector<byte> m_message;
00164          };
00165 
00166       struct Message_Info
00167          {
00168          Message_Info(u16bit e, Handshake_Type mt, const std::vector<byte>& msg) :
00169             epoch(e), msg_type(mt), msg_bits(msg) {}
00170 
00171          Message_Info(const Message_Info& other) = default;
00172 
00173          Message_Info() : epoch(0xFFFF), msg_type(HANDSHAKE_NONE) {}
00174 
00175          u16bit epoch;
00176          Handshake_Type msg_type;
00177          std::vector<byte> msg_bits;
00178          };
00179 
00180       class Connection_Sequence_Numbers& m_seqs;
00181       std::map<u16bit, Handshake_Reassembly> m_messages;
00182       std::set<u16bit> m_ccs_epochs;
00183       std::vector<std::vector<u16bit>> m_flights;
00184       std::map<u16bit, Message_Info> m_flight_data;
00185 
00186       u64bit m_last_write = 0;
00187       u64bit m_next_timeout = 0;
00188 
00189       u16bit m_in_message_seq = 0;
00190       u16bit m_out_message_seq = 0;
00191 
00192       writer_fn m_send_hs;
00193       u16bit m_mtu;
00194    };
00195 
00196 }
00197 
00198 }
00199 
00200 #endif