Botan 3.0.0
Crypto and TLS for C&
tls_handshake_io.h
Go to the documentation of this file.
1/*
2* TLS Handshake Serialization
3* (C) 2012,2014 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_TLS_HANDSHAKE_IO_H_
9#define BOTAN_TLS_HANDSHAKE_IO_H_
10
11#include <botan/tls_magic.h>
12#include <botan/tls_version.h>
13#include <botan/internal/tls_channel_impl.h>
14#include <functional>
15#include <vector>
16#include <deque>
17#include <map>
18#include <set>
19#include <utility>
20
21namespace Botan {
22
23namespace TLS {
24
25class Handshake_Message;
26
27/**
28* Handshake IO Interface
29*
30* This interface abstracts over stream and datagram processing of handshake
31* messages. It receives individual records from the channel via `add_record` and provides a
32* sending interface via a callback function provided by the channel.
33*
34* Handshake message headers are parsed and removed in `get_next_record`. The
35* result is provided back to the channel via
36* `Handshake_State::get_next_handshake_msg`.
37*
38* `send` is used by individual handshake message implementations, which send
39* themselves, as well as both client and server to dispatch CCS messaged (and
40* Hello_Verify_Request in the server case). Before calling the `writer_fn`,
41* `format` is called to add the handshake message header (except for CCS).
42*
43* The buffer returned by `send` is used to update the transcript record hash
44* (where desired).
45*/
47 {
48 public:
50
51 virtual std::vector<uint8_t> send(const Handshake_Message& msg) = 0;
52
53 virtual std::vector<uint8_t> send_under_epoch(const Handshake_Message& msg, uint16_t epoch) = 0;
54
55 virtual bool timeout_check() = 0;
56
57 virtual bool have_more_data() const = 0;
58
59 virtual std::vector<uint8_t> format(
60 const std::vector<uint8_t>& handshake_msg,
61 Handshake_Type handshake_type) const = 0;
62
63 virtual void add_record(const uint8_t record[],
64 size_t record_len,
65 Record_Type type,
66 uint64_t sequence_number) = 0;
67
68 /**
69 * Returns (HANDSHAKE_NONE, std::vector<>()) if no message currently available
70 */
71 virtual std::pair<Handshake_Type, std::vector<uint8_t>>
72 get_next_record(bool expecting_ccs) = 0;
73
74 Handshake_IO() = default;
75
76 Handshake_IO(const Handshake_IO&) = delete;
77
79
80 virtual ~Handshake_IO() = default;
81 };
82
83/**
84* Handshake IO for stream-based handshakes
85*/
87 {
88 public:
89 typedef std::function<void (Record_Type, const std::vector<uint8_t>&)> writer_fn;
90
91 explicit Stream_Handshake_IO(writer_fn writer) : m_send_hs(writer) {}
92
94
95 bool timeout_check() override { return false; }
96
97 bool have_more_data() const override { return m_queue.empty() == false; }
98
99 std::vector<uint8_t> send(const Handshake_Message& msg) override;
100
101 std::vector<uint8_t> send_under_epoch(const Handshake_Message& msg, uint16_t epoch) override;
102
103 std::vector<uint8_t> format(
104 const std::vector<uint8_t>& handshake_msg,
105 Handshake_Type handshake_type) const override;
106
107 void add_record(const uint8_t record[],
108 size_t record_len,
109 Record_Type type,
110 uint64_t sequence_number) override;
111
112 std::pair<Handshake_Type, std::vector<uint8_t>>
113 get_next_record(bool expecting_ccs) override;
114 private:
115 std::deque<uint8_t> m_queue;
116 writer_fn m_send_hs;
117 };
118
119/**
120* Handshake IO for datagram-based handshakes
121*/
123 {
124 public:
125 typedef std::function<void (uint16_t, Record_Type, const std::vector<uint8_t>&)> writer_fn;
126
129 uint16_t mtu, uint64_t initial_timeout_ms, uint64_t max_timeout_ms) :
130 m_seqs(seq),
131 m_flights(1),
132 m_initial_timeout(initial_timeout_ms),
133 m_max_timeout(max_timeout_ms),
134 m_send_hs(writer),
135 m_mtu(mtu)
136 {}
137
139
140 bool timeout_check() override;
141
142 bool have_more_data() const override;
143
144 std::vector<uint8_t> send(const Handshake_Message& msg) override;
145
146 std::vector<uint8_t> send_under_epoch(const Handshake_Message& msg, uint16_t epoch) override;
147
148 std::vector<uint8_t> format(
149 const std::vector<uint8_t>& handshake_msg,
150 Handshake_Type handshake_type) const override;
151
152 void add_record(const uint8_t record[],
153 size_t record_len,
154 Record_Type type,
155 uint64_t sequence_number) override;
156
157 std::pair<Handshake_Type, std::vector<uint8_t>>
158 get_next_record(bool expecting_ccs) override;
159 private:
160 void retransmit_flight(size_t flight);
161 void retransmit_last_flight();
162
163 std::vector<uint8_t> format_fragment(
164 const uint8_t fragment[],
165 size_t fragment_len,
166 uint16_t frag_offset,
167 uint16_t msg_len,
168 Handshake_Type type,
169 uint16_t msg_sequence) const;
170
171 std::vector<uint8_t> format_w_seq(
172 const std::vector<uint8_t>& handshake_msg,
173 Handshake_Type handshake_type,
174 uint16_t msg_sequence) const;
175
176 std::vector<uint8_t> send_message(uint16_t msg_seq, uint16_t epoch,
177 Handshake_Type msg_type,
178 const std::vector<uint8_t>& msg);
179
180 class Handshake_Reassembly final
181 {
182 public:
183 void add_fragment(const uint8_t fragment[],
184 size_t fragment_length,
185 size_t fragment_offset,
186 uint16_t epoch,
187 Handshake_Type msg_type,
188 size_t msg_length);
189
190 bool complete() const;
191
192 uint16_t epoch() const { return m_epoch; }
193
194 std::pair<Handshake_Type, std::vector<uint8_t>> message() const;
195 private:
197 size_t m_msg_length = 0;
198 uint16_t m_epoch = 0;
199
200 // vector<bool> m_seen;
201 // vector<uint8_t> m_fragments
202 std::map<size_t, uint8_t> m_fragments;
203 std::vector<uint8_t> m_message;
204 };
205
206 struct Message_Info final
207 {
208 Message_Info(uint16_t e, Handshake_Type mt, const std::vector<uint8_t>& msg) :
209 epoch(e), msg_type(mt), msg_bits(msg) {}
210
211 Message_Info() : epoch(0xFFFF), msg_type(Handshake_Type::None) {}
212
213 uint16_t epoch;
214 Handshake_Type msg_type;
215 std::vector<uint8_t> msg_bits;
216 };
217
218 class Connection_Sequence_Numbers& m_seqs;
219 std::map<uint16_t, Handshake_Reassembly> m_messages;
220 std::set<uint16_t> m_ccs_epochs;
221 std::vector<std::vector<uint16_t>> m_flights;
222 std::map<uint16_t, Message_Info> m_flight_data;
223
224 uint64_t m_initial_timeout = 0;
225 uint64_t m_max_timeout = 0;
226
227 uint64_t m_last_write = 0;
228 uint64_t m_next_timeout = 0;
229
230 uint16_t m_in_message_seq = 0;
231 uint16_t m_out_message_seq = 0;
232
233 writer_fn m_send_hs;
234 uint16_t m_mtu;
235 };
236
237}
238
239}
240
241#endif
std::function< void(uint16_t, Record_Type, const std::vector< uint8_t > &)> writer_fn
std::vector< uint8_t > send_under_epoch(const Handshake_Message &msg, uint16_t epoch) override
void add_record(const uint8_t record[], size_t record_len, Record_Type type, uint64_t sequence_number) override
std::pair< Handshake_Type, std::vector< uint8_t > > get_next_record(bool expecting_ccs) override
std::vector< uint8_t > format(const std::vector< uint8_t > &handshake_msg, Handshake_Type handshake_type) const override
Protocol_Version initial_record_version() const override
std::vector< uint8_t > send(const Handshake_Message &msg) override
Datagram_Handshake_IO(writer_fn writer, class Connection_Sequence_Numbers &seq, uint16_t mtu, uint64_t initial_timeout_ms, uint64_t max_timeout_ms)
virtual std::vector< uint8_t > send_under_epoch(const Handshake_Message &msg, uint16_t epoch)=0
Handshake_IO(const Handshake_IO &)=delete
virtual bool timeout_check()=0
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
Handshake_IO & operator=(const Handshake_IO &)=delete
virtual void add_record(const uint8_t record[], size_t record_len, Record_Type type, uint64_t sequence_number)=0
virtual Protocol_Version initial_record_version() const =0
virtual std::vector< uint8_t > format(const std::vector< uint8_t > &handshake_msg, Handshake_Type handshake_type) const =0
virtual ~Handshake_IO()=default
virtual bool have_more_data() const =0
virtual std::pair< Handshake_Type, std::vector< uint8_t > > get_next_record(bool expecting_ccs)=0
bool have_more_data() const override
std::vector< uint8_t > send_under_epoch(const Handshake_Message &msg, uint16_t epoch) override
std::function< void(Record_Type, const std::vector< uint8_t > &)> writer_fn
Stream_Handshake_IO(writer_fn writer)
std::vector< uint8_t > format(const std::vector< uint8_t > &handshake_msg, Handshake_Type handshake_type) const override
Protocol_Version initial_record_version() const override
std::pair< Handshake_Type, std::vector< uint8_t > > get_next_record(bool expecting_ccs) override
std::vector< uint8_t > send(const Handshake_Message &msg) override
void add_record(const uint8_t record[], size_t record_len, Record_Type type, uint64_t sequence_number) override
int(* final)(unsigned char *, CTX *)
Definition: alg_id.cpp:12