Coverage Report

Created: 2022-11-24 06:56

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