Coverage Report

Created: 2021-05-04 09:02

/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
class Handshake_IO
30
   {
31
   public:
32
      virtual Protocol_Version initial_record_version() const = 0;
33
34
      virtual std::vector<uint8_t> send(const Handshake_Message& msg) = 0;
35
36
      virtual std::vector<uint8_t> send_under_epoch(const Handshake_Message& msg, uint16_t epoch) = 0;
37
38
      virtual bool timeout_check() = 0;
39
40
      virtual bool have_more_data() const = 0;
41
42
      virtual std::vector<uint8_t> format(
43
         const std::vector<uint8_t>& handshake_msg,
44
         Handshake_Type handshake_type) const = 0;
45
46
      virtual void add_record(const uint8_t record[],
47
                              size_t record_len,
48
                              Record_Type type,
49
                              uint64_t sequence_number) = 0;
50
51
      /**
52
      * Returns (HANDSHAKE_NONE, std::vector<>()) if no message currently available
53
      */
54
      virtual std::pair<Handshake_Type, std::vector<uint8_t>>
55
         get_next_record(bool expecting_ccs) = 0;
56
57
47.8k
      Handshake_IO() = default;
58
59
      Handshake_IO(const Handshake_IO&) = delete;
60
61
      Handshake_IO& operator=(const Handshake_IO&) = delete;
62
63
47.8k
      virtual ~Handshake_IO() = default;
64
   };
65
66
/**
67
* Handshake IO for stream-based handshakes
68
*/
69
class Stream_Handshake_IO final : public Handshake_IO
70
   {
71
   public:
72
      typedef std::function<void (uint8_t, const std::vector<uint8_t>&)> writer_fn;
73
74
47.1k
      explicit Stream_Handshake_IO(writer_fn writer) : m_send_hs(writer) {}
75
76
      Protocol_Version initial_record_version() const override;
77
78
0
      bool timeout_check() override { return false; }
79
80
34.6k
      bool have_more_data() const override { return m_queue.empty() == false; }
81
82
      std::vector<uint8_t> send(const Handshake_Message& msg) override;
83
84
      std::vector<uint8_t> send_under_epoch(const Handshake_Message& msg, uint16_t epoch) override;
85
86
      std::vector<uint8_t> format(
87
         const std::vector<uint8_t>& handshake_msg,
88
         Handshake_Type handshake_type) const override;
89
90
      void add_record(const uint8_t record[],
91
                      size_t record_len,
92
                      Record_Type type,
93
                      uint64_t sequence_number) override;
94
95
      std::pair<Handshake_Type, std::vector<uint8_t>>
96
         get_next_record(bool expecting_ccs) override;
97
   private:
98
      std::deque<uint8_t> m_queue;
99
      writer_fn m_send_hs;
100
   };
101
102
/**
103
* Handshake IO for datagram-based handshakes
104
*/
105
class Datagram_Handshake_IO final : public Handshake_IO
106
   {
107
   public:
108
      typedef std::function<void (uint16_t, uint8_t, const std::vector<uint8_t>&)> writer_fn;
109
110
      Datagram_Handshake_IO(writer_fn writer,
111
                            class Connection_Sequence_Numbers& seq,
112
                            uint16_t mtu, uint64_t initial_timeout_ms, uint64_t max_timeout_ms) :
113
         m_seqs(seq),
114
         m_flights(1),
115
         m_initial_timeout(initial_timeout_ms),
116
         m_max_timeout(max_timeout_ms),
117
         m_send_hs(writer),
118
         m_mtu(mtu)
119
659
         {}
120
121
      Protocol_Version initial_record_version() const override;
122
123
      bool timeout_check() override;
124
125
      bool have_more_data() const override;
126
127
      std::vector<uint8_t> send(const Handshake_Message& msg) override;
128
129
      std::vector<uint8_t> send_under_epoch(const Handshake_Message& msg, uint16_t epoch) override;
130
131
      std::vector<uint8_t> format(
132
         const std::vector<uint8_t>& handshake_msg,
133
         Handshake_Type handshake_type) const override;
134
135
      void add_record(const uint8_t record[],
136
                      size_t record_len,
137
                      Record_Type type,
138
                      uint64_t sequence_number) override;
139
140
      std::pair<Handshake_Type, std::vector<uint8_t>>
141
         get_next_record(bool expecting_ccs) override;
142
   private:
143
      void retransmit_flight(size_t flight);
144
      void retransmit_last_flight();
145
146
      std::vector<uint8_t> format_fragment(
147
         const uint8_t fragment[],
148
         size_t fragment_len,
149
         uint16_t frag_offset,
150
         uint16_t msg_len,
151
         Handshake_Type type,
152
         uint16_t msg_sequence) const;
153
154
      std::vector<uint8_t> format_w_seq(
155
         const std::vector<uint8_t>& handshake_msg,
156
         Handshake_Type handshake_type,
157
         uint16_t msg_sequence) const;
158
159
      std::vector<uint8_t> send_message(uint16_t msg_seq, uint16_t epoch,
160
                                     Handshake_Type msg_type,
161
                                     const std::vector<uint8_t>& msg);
162
163
      class Handshake_Reassembly final
164
         {
165
         public:
166
            void add_fragment(const uint8_t fragment[],
167
                              size_t fragment_length,
168
                              size_t fragment_offset,
169
                              uint16_t epoch,
170
                              uint8_t msg_type,
171
                              size_t msg_length);
172
173
            bool complete() const;
174
175
0
            uint16_t epoch() const { return m_epoch; }
176
177
            std::pair<Handshake_Type, std::vector<uint8_t>> message() const;
178
         private:
179
            uint8_t m_msg_type = HANDSHAKE_NONE;
180
            size_t m_msg_length = 0;
181
            uint16_t m_epoch = 0;
182
183
            // vector<bool> m_seen;
184
            // vector<uint8_t> m_fragments
185
            std::map<size_t, uint8_t> m_fragments;
186
            std::vector<uint8_t> m_message;
187
         };
188
189
      struct Message_Info final
190
         {
191
         Message_Info(uint16_t e, Handshake_Type mt, const std::vector<uint8_t>& msg) :
192
0
            epoch(e), msg_type(mt), msg_bits(msg) {}
193
194
0
         Message_Info() : epoch(0xFFFF), msg_type(HANDSHAKE_NONE) {}
195
196
         uint16_t epoch;
197
         Handshake_Type msg_type;
198
         std::vector<uint8_t> msg_bits;
199
         };
200
201
      class Connection_Sequence_Numbers& m_seqs;
202
      std::map<uint16_t, Handshake_Reassembly> m_messages;
203
      std::set<uint16_t> m_ccs_epochs;
204
      std::vector<std::vector<uint16_t>> m_flights;
205
      std::map<uint16_t, Message_Info> m_flight_data;
206
207
      uint64_t m_initial_timeout = 0;
208
      uint64_t m_max_timeout = 0;
209
210
      uint64_t m_last_write = 0;
211
      uint64_t m_next_timeout = 0;
212
213
      uint16_t m_in_message_seq = 0;
214
      uint16_t m_out_message_seq = 0;
215
216
      writer_fn m_send_hs;
217
      uint16_t m_mtu;
218
   };
219
220
}
221
222
}
223
224
#endif