/src/botan/src/lib/tls/tls_extensions.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * TLS Extensions |
3 | | * (C) 2011,2012,2015,2016 Jack Lloyd |
4 | | * 2016 Juraj Somorovsky |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #include <botan/tls_extensions.h> |
10 | | #include <botan/internal/tls_reader.h> |
11 | | #include <botan/tls_exceptn.h> |
12 | | #include <botan/tls_policy.h> |
13 | | |
14 | | namespace Botan { |
15 | | |
16 | | namespace TLS { |
17 | | |
18 | | namespace { |
19 | | |
20 | | Extension* make_extension(TLS_Data_Reader& reader, uint16_t code, uint16_t size, Connection_Side from) |
21 | 191k | { |
22 | 191k | switch(code) |
23 | 191k | { |
24 | 6.21k | case TLSEXT_SERVER_NAME_INDICATION: |
25 | 6.21k | return new Server_Name_Indicator(reader, size); |
26 | 0 | |
27 | 0 | #if defined(BOTAN_HAS_SRP6) |
28 | 71 | case TLSEXT_SRP_IDENTIFIER: |
29 | 71 | return new SRP_Identifier(reader, size); |
30 | 0 | #endif |
31 | 0 | |
32 | 18.7k | case TLSEXT_SUPPORTED_GROUPS: |
33 | 18.7k | return new Supported_Groups(reader, size); |
34 | 0 | |
35 | 1.29k | case TLSEXT_CERT_STATUS_REQUEST: |
36 | 1.29k | return new Certificate_Status_Request(reader, size, from); |
37 | 0 | |
38 | 1.72k | case TLSEXT_EC_POINT_FORMATS: |
39 | 1.72k | return new Supported_Point_Formats(reader, size); |
40 | 0 | |
41 | 4.10k | case TLSEXT_SAFE_RENEGOTIATION: |
42 | 4.10k | return new Renegotiation_Extension(reader, size); |
43 | 0 | |
44 | 2.75k | case TLSEXT_SIGNATURE_ALGORITHMS: |
45 | 2.75k | return new Signature_Algorithms(reader, size); |
46 | 0 | |
47 | 126 | case TLSEXT_USE_SRTP: |
48 | 126 | return new SRTP_Protection_Profiles(reader, size); |
49 | 0 | |
50 | 9.25k | case TLSEXT_ALPN: |
51 | 9.25k | return new Application_Layer_Protocol_Notification(reader, size); |
52 | 0 | |
53 | 6.70k | case TLSEXT_EXTENDED_MASTER_SECRET: |
54 | 6.70k | return new Extended_Master_Secret(reader, size); |
55 | 0 | |
56 | 2.99k | case TLSEXT_ENCRYPT_THEN_MAC: |
57 | 2.99k | return new Encrypt_then_MAC(reader, size); |
58 | 0 | |
59 | 2.70k | case TLSEXT_SESSION_TICKET: |
60 | 2.70k | return new Session_Ticket(reader, size); |
61 | 0 | |
62 | 128 | case TLSEXT_SUPPORTED_VERSIONS: |
63 | 128 | return new Supported_Versions(reader, size, from); |
64 | 134k | } |
65 | 134k | |
66 | 134k | return new Unknown_Extension(static_cast<Handshake_Extension_Type>(code), |
67 | 134k | reader, size); |
68 | 134k | } |
69 | | |
70 | | } |
71 | | |
72 | | void Extensions::deserialize(TLS_Data_Reader& reader, Connection_Side from) |
73 | 35.9k | { |
74 | 35.9k | if(reader.has_remaining()) |
75 | 34.6k | { |
76 | 34.6k | const uint16_t all_extn_size = reader.get_uint16_t(); |
77 | 34.6k | |
78 | 34.6k | if(reader.remaining_bytes() != all_extn_size) |
79 | 141 | throw Decoding_Error("Bad extension size"); |
80 | 34.4k | |
81 | 226k | while(reader.has_remaining()) |
82 | 191k | { |
83 | 191k | const uint16_t extension_code = reader.get_uint16_t(); |
84 | 191k | const uint16_t extension_size = reader.get_uint16_t(); |
85 | 191k | |
86 | 191k | const auto type = static_cast<Handshake_Extension_Type>(extension_code); |
87 | 191k | |
88 | 191k | if(m_extensions.find(type) != m_extensions.end()) |
89 | 14 | throw TLS_Exception(TLS::Alert::DECODE_ERROR, |
90 | 14 | "Peer sent duplicated extensions"); |
91 | 191k | |
92 | 191k | Extension* extn = make_extension( |
93 | 191k | reader, extension_code, extension_size, from); |
94 | 191k | |
95 | 191k | this->add(extn); |
96 | 191k | } |
97 | 34.4k | } |
98 | 35.9k | } |
99 | | |
100 | | std::vector<uint8_t> Extensions::serialize(Connection_Side whoami) const |
101 | 28.0k | { |
102 | 28.0k | std::vector<uint8_t> buf(2); // 2 bytes for length field |
103 | 28.0k | |
104 | 28.0k | for(auto& extn : m_extensions) |
105 | 74.5k | { |
106 | 74.5k | if(extn.second->empty()) |
107 | 5.24k | continue; |
108 | 69.3k | |
109 | 69.3k | const uint16_t extn_code = static_cast<uint16_t>(extn.second->type()); |
110 | 69.3k | |
111 | 69.3k | const std::vector<uint8_t> extn_val = extn.second->serialize(whoami); |
112 | 69.3k | |
113 | 69.3k | buf.push_back(get_byte(0, extn_code)); |
114 | 69.3k | buf.push_back(get_byte(1, extn_code)); |
115 | 69.3k | |
116 | 69.3k | buf.push_back(get_byte(0, static_cast<uint16_t>(extn_val.size()))); |
117 | 69.3k | buf.push_back(get_byte(1, static_cast<uint16_t>(extn_val.size()))); |
118 | 69.3k | |
119 | 69.3k | buf += extn_val; |
120 | 69.3k | } |
121 | 28.0k | |
122 | 28.0k | const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2); |
123 | 28.0k | |
124 | 28.0k | buf[0] = get_byte(0, extn_size); |
125 | 28.0k | buf[1] = get_byte(1, extn_size); |
126 | 28.0k | |
127 | 28.0k | // avoid sending a completely empty extensions block |
128 | 28.0k | if(buf.size() == 2) |
129 | 11.5k | return std::vector<uint8_t>(); |
130 | 16.4k | |
131 | 16.4k | return buf; |
132 | 16.4k | } |
133 | | |
134 | | bool Extensions::remove_extension(Handshake_Extension_Type typ) |
135 | 0 | { |
136 | 0 | auto i = m_extensions.find(typ); |
137 | 0 | if(i == m_extensions.end()) |
138 | 0 | return false; |
139 | 0 | m_extensions.erase(i); |
140 | 0 | return true; |
141 | 0 | } |
142 | | |
143 | | std::set<Handshake_Extension_Type> Extensions::extension_types() const |
144 | 24.1k | { |
145 | 24.1k | std::set<Handshake_Extension_Type> offers; |
146 | 205k | for(auto i = m_extensions.begin(); i != m_extensions.end(); ++i) |
147 | 180k | offers.insert(i->first); |
148 | 24.1k | return offers; |
149 | 24.1k | } |
150 | | |
151 | | Unknown_Extension::Unknown_Extension(Handshake_Extension_Type type, |
152 | | TLS_Data_Reader& reader, |
153 | | uint16_t extension_size) : |
154 | | m_type(type), |
155 | | m_value(reader.get_fixed<uint8_t>(extension_size)) |
156 | 134k | { |
157 | 134k | } |
158 | | |
159 | | std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const |
160 | 0 | { |
161 | 0 | throw Invalid_State("Cannot encode an unknown TLS extension"); |
162 | 0 | } |
163 | | |
164 | | Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, |
165 | | uint16_t extension_size) |
166 | 6.21k | { |
167 | 6.21k | /* |
168 | 6.21k | * This is used by the server to confirm that it knew the name |
169 | 6.21k | */ |
170 | 6.21k | if(extension_size == 0) |
171 | 5.90k | return; |
172 | 315 | |
173 | 315 | uint16_t name_bytes = reader.get_uint16_t(); |
174 | 315 | |
175 | 315 | if(name_bytes + 2 != extension_size) |
176 | 78 | throw Decoding_Error("Bad encoding of SNI extension"); |
177 | 237 | |
178 | 1.10k | while(name_bytes) |
179 | 871 | { |
180 | 871 | uint8_t name_type = reader.get_byte(); |
181 | 871 | name_bytes--; |
182 | 871 | |
183 | 871 | if(name_type == 0) // DNS |
184 | 685 | { |
185 | 685 | m_sni_host_name = reader.get_string(2, 1, 65535); |
186 | 685 | name_bytes -= static_cast<uint16_t>(2 + m_sni_host_name.size()); |
187 | 685 | } |
188 | 186 | else // some other unknown name type |
189 | 186 | { |
190 | 186 | reader.discard_next(name_bytes); |
191 | 186 | name_bytes = 0; |
192 | 186 | } |
193 | 871 | } |
194 | 237 | } |
195 | | |
196 | | std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side /*whoami*/) const |
197 | 5.24k | { |
198 | 5.24k | std::vector<uint8_t> buf; |
199 | 5.24k | |
200 | 5.24k | size_t name_len = m_sni_host_name.size(); |
201 | 5.24k | |
202 | 5.24k | buf.push_back(get_byte(0, static_cast<uint16_t>(name_len+3))); |
203 | 5.24k | buf.push_back(get_byte(1, static_cast<uint16_t>(name_len+3))); |
204 | 5.24k | buf.push_back(0); // DNS |
205 | 5.24k | |
206 | 5.24k | buf.push_back(get_byte(0, static_cast<uint16_t>(name_len))); |
207 | 5.24k | buf.push_back(get_byte(1, static_cast<uint16_t>(name_len))); |
208 | 5.24k | |
209 | 5.24k | buf += std::make_pair( |
210 | 5.24k | cast_char_ptr_to_uint8(m_sni_host_name.data()), |
211 | 5.24k | m_sni_host_name.size()); |
212 | 5.24k | |
213 | 5.24k | return buf; |
214 | 5.24k | } |
215 | | |
216 | | #if defined(BOTAN_HAS_SRP6) |
217 | | |
218 | | SRP_Identifier::SRP_Identifier(TLS_Data_Reader& reader, |
219 | | uint16_t extension_size) : m_srp_identifier(reader.get_string(1, 1, 255)) |
220 | 71 | { |
221 | 71 | if(m_srp_identifier.size() + 1 != extension_size) |
222 | 33 | throw Decoding_Error("Bad encoding for SRP identifier extension"); |
223 | 71 | } |
224 | | |
225 | | std::vector<uint8_t> SRP_Identifier::serialize(Connection_Side /*whoami*/) const |
226 | 0 | { |
227 | 0 | std::vector<uint8_t> buf; |
228 | 0 |
|
229 | 0 | const uint8_t* srp_bytes = cast_char_ptr_to_uint8(m_srp_identifier.data()); |
230 | 0 | append_tls_length_value(buf, srp_bytes, m_srp_identifier.size(), 1); |
231 | 0 |
|
232 | 0 | return buf; |
233 | 0 | } |
234 | | |
235 | | #endif |
236 | | |
237 | | Renegotiation_Extension::Renegotiation_Extension(TLS_Data_Reader& reader, |
238 | | uint16_t extension_size) : m_reneg_data(reader.get_range<uint8_t>(1, 0, 255)) |
239 | 4.10k | { |
240 | 4.10k | if(m_reneg_data.size() + 1 != extension_size) |
241 | 49 | throw Decoding_Error("Bad encoding for secure renegotiation extn"); |
242 | 4.10k | } |
243 | | |
244 | | std::vector<uint8_t> Renegotiation_Extension::serialize(Connection_Side /*whoami*/) const |
245 | 10.1k | { |
246 | 10.1k | std::vector<uint8_t> buf; |
247 | 10.1k | append_tls_length_value(buf, m_reneg_data, 1); |
248 | 10.1k | return buf; |
249 | 10.1k | } |
250 | | |
251 | | Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader, |
252 | | uint16_t extension_size) |
253 | 9.25k | { |
254 | 9.25k | if(extension_size == 0) |
255 | 5.21k | return; // empty extension |
256 | 4.03k | |
257 | 4.03k | const uint16_t name_bytes = reader.get_uint16_t(); |
258 | 4.03k | |
259 | 4.03k | size_t bytes_remaining = extension_size - 2; |
260 | 4.03k | |
261 | 4.03k | if(name_bytes != bytes_remaining) |
262 | 115 | throw Decoding_Error("Bad encoding of ALPN extension, bad length field"); |
263 | 3.92k | |
264 | 33.9k | while(bytes_remaining) |
265 | 30.0k | { |
266 | 30.0k | const std::string p = reader.get_string(1, 0, 255); |
267 | 30.0k | |
268 | 30.0k | if(bytes_remaining < p.size() + 1) |
269 | 3 | throw Decoding_Error("Bad encoding of ALPN, length field too long"); |
270 | 30.0k | |
271 | 30.0k | if(p.empty()) |
272 | 88 | throw Decoding_Error("Empty ALPN protocol not allowed"); |
273 | 30.0k | |
274 | 30.0k | bytes_remaining -= (p.size() + 1); |
275 | 30.0k | |
276 | 30.0k | m_protocols.push_back(p); |
277 | 30.0k | } |
278 | 3.92k | } |
279 | | |
280 | | const std::string& Application_Layer_Protocol_Notification::single_protocol() const |
281 | 0 | { |
282 | 0 | if(m_protocols.size() != 1) |
283 | 0 | throw TLS_Exception(Alert::HANDSHAKE_FAILURE, |
284 | 0 | "Server sent " + std::to_string(m_protocols.size()) + |
285 | 0 | " protocols in ALPN extension response"); |
286 | 0 | return m_protocols[0]; |
287 | 0 | } |
288 | | |
289 | | std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const |
290 | 5.13k | { |
291 | 5.13k | std::vector<uint8_t> buf(2); |
292 | 5.13k | |
293 | 5.13k | for(auto&& p: m_protocols) |
294 | 5.13k | { |
295 | 5.13k | if(p.length() >= 256) |
296 | 0 | throw TLS_Exception(Alert::INTERNAL_ERROR, "ALPN name too long"); |
297 | 5.13k | if(p != "") |
298 | 5.13k | append_tls_length_value(buf, |
299 | 5.13k | cast_char_ptr_to_uint8(p.data()), |
300 | 5.13k | p.size(), |
301 | 5.13k | 1); |
302 | 5.13k | } |
303 | 5.13k | |
304 | 5.13k | buf[0] = get_byte(0, static_cast<uint16_t>(buf.size()-2)); |
305 | 5.13k | buf[1] = get_byte(1, static_cast<uint16_t>(buf.size()-2)); |
306 | 5.13k | |
307 | 5.13k | return buf; |
308 | 5.13k | } |
309 | | |
310 | | Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) |
311 | 5.24k | { |
312 | 5.24k | } |
313 | | |
314 | | std::vector<Group_Params> Supported_Groups::ec_groups() const |
315 | 39.8k | { |
316 | 39.8k | std::vector<Group_Params> ec; |
317 | 39.8k | for(auto g : m_groups) |
318 | 203k | { |
319 | 203k | if(group_param_is_dh(g) == false) |
320 | 155k | ec.push_back(g); |
321 | 203k | } |
322 | 39.8k | return ec; |
323 | 39.8k | } |
324 | | |
325 | | std::vector<Group_Params> Supported_Groups::dh_groups() const |
326 | 1.82k | { |
327 | 1.82k | std::vector<Group_Params> dh; |
328 | 1.82k | for(auto g : m_groups) |
329 | 8.08k | { |
330 | 8.08k | if(group_param_is_dh(g) == true) |
331 | 3.03k | dh.push_back(g); |
332 | 8.08k | } |
333 | 1.82k | return dh; |
334 | 1.82k | } |
335 | | |
336 | | std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const |
337 | 5.24k | { |
338 | 5.24k | std::vector<uint8_t> buf(2); |
339 | 5.24k | |
340 | 5.24k | for(auto g : m_groups) |
341 | 62.8k | { |
342 | 62.8k | const uint16_t id = static_cast<uint16_t>(g); |
343 | 62.8k | |
344 | 62.8k | if(id > 0) |
345 | 62.8k | { |
346 | 62.8k | buf.push_back(get_byte(0, id)); |
347 | 62.8k | buf.push_back(get_byte(1, id)); |
348 | 62.8k | } |
349 | 62.8k | } |
350 | 5.24k | |
351 | 5.24k | buf[0] = get_byte(0, static_cast<uint16_t>(buf.size()-2)); |
352 | 5.24k | buf[1] = get_byte(1, static_cast<uint16_t>(buf.size()-2)); |
353 | 5.24k | |
354 | 5.24k | return buf; |
355 | 5.24k | } |
356 | | |
357 | | Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, |
358 | | uint16_t extension_size) |
359 | 18.7k | { |
360 | 18.7k | const uint16_t len = reader.get_uint16_t(); |
361 | 18.7k | |
362 | 18.7k | if(len + 2 != extension_size) |
363 | 59 | throw Decoding_Error("Inconsistent length field in supported groups list"); |
364 | 18.6k | |
365 | 18.6k | if(len % 2 == 1) |
366 | 3 | throw Decoding_Error("Supported groups list of strange size"); |
367 | 18.6k | |
368 | 18.6k | const size_t elems = len / 2; |
369 | 18.6k | |
370 | 110k | for(size_t i = 0; i != elems; ++i) |
371 | 92.0k | { |
372 | 92.0k | const uint16_t id = reader.get_uint16_t(); |
373 | 92.0k | m_groups.push_back(static_cast<Group_Params>(id)); |
374 | 92.0k | } |
375 | 18.6k | } |
376 | | |
377 | | std::vector<uint8_t> Supported_Point_Formats::serialize(Connection_Side /*whoami*/) const |
378 | 5.81k | { |
379 | 5.81k | // if this extension is sent, it MUST include uncompressed (RFC 4492, section 5.1) |
380 | 5.81k | if(m_prefers_compressed) |
381 | 0 | { |
382 | 0 | return std::vector<uint8_t>{2, ANSIX962_COMPRESSED_PRIME, UNCOMPRESSED}; |
383 | 0 | } |
384 | 5.81k | else |
385 | 5.81k | { |
386 | 5.81k | return std::vector<uint8_t>{1, UNCOMPRESSED}; |
387 | 5.81k | } |
388 | 5.81k | } |
389 | | |
390 | | Supported_Point_Formats::Supported_Point_Formats(TLS_Data_Reader& reader, |
391 | | uint16_t extension_size) |
392 | 1.72k | { |
393 | 1.72k | uint8_t len = reader.get_byte(); |
394 | 1.72k | |
395 | 1.72k | if(len + 1 != extension_size) |
396 | 60 | throw Decoding_Error("Inconsistent length field in supported point formats list"); |
397 | 1.66k | |
398 | 4.42k | for(size_t i = 0; i != len; ++i) |
399 | 3.52k | { |
400 | 3.52k | uint8_t format = reader.get_byte(); |
401 | 3.52k | |
402 | 3.52k | if(static_cast<ECPointFormat>(format) == UNCOMPRESSED) |
403 | 638 | { |
404 | 638 | m_prefers_compressed = false; |
405 | 638 | reader.discard_next(len-i-1); |
406 | 638 | return; |
407 | 638 | } |
408 | 2.88k | else if(static_cast<ECPointFormat>(format) == ANSIX962_COMPRESSED_PRIME) |
409 | 125 | { |
410 | 125 | m_prefers_compressed = true; |
411 | 125 | reader.discard_next(len-i-1); |
412 | 125 | return; |
413 | 125 | } |
414 | 3.52k | |
415 | 3.52k | // ignore ANSIX962_COMPRESSED_CHAR2, we don't support these curves |
416 | 3.52k | } |
417 | 1.66k | } |
418 | | |
419 | | std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const |
420 | 5.24k | { |
421 | 5.24k | BOTAN_ASSERT(m_schemes.size() < 256, "Too many signature schemes"); |
422 | 5.24k | |
423 | 5.24k | std::vector<uint8_t> buf; |
424 | 5.24k | |
425 | 5.24k | const uint16_t len = static_cast<uint16_t>(m_schemes.size() * 2); |
426 | 5.24k | |
427 | 5.24k | buf.push_back(get_byte(0, len)); |
428 | 5.24k | buf.push_back(get_byte(1, len)); |
429 | 5.24k | |
430 | 5.24k | for(Signature_Scheme scheme : m_schemes) |
431 | 47.1k | { |
432 | 47.1k | const uint16_t scheme_code = static_cast<uint16_t>(scheme); |
433 | 47.1k | |
434 | 47.1k | buf.push_back(get_byte(0, scheme_code)); |
435 | 47.1k | buf.push_back(get_byte(1, scheme_code)); |
436 | 47.1k | } |
437 | 5.24k | |
438 | 5.24k | return buf; |
439 | 5.24k | } |
440 | | |
441 | | Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, |
442 | | uint16_t extension_size) |
443 | 2.75k | { |
444 | 2.75k | uint16_t len = reader.get_uint16_t(); |
445 | 2.75k | |
446 | 2.75k | if(len + 2 != extension_size || len % 2 == 1 || len == 0) |
447 | 73 | { |
448 | 73 | throw Decoding_Error("Bad encoding on signature algorithms extension"); |
449 | 73 | } |
450 | 2.68k | |
451 | 44.8k | while(len) |
452 | 42.1k | { |
453 | 42.1k | const uint16_t scheme_code = reader.get_uint16_t(); |
454 | 42.1k | m_schemes.push_back(static_cast<Signature_Scheme>(scheme_code)); |
455 | 42.1k | len -= 2; |
456 | 42.1k | } |
457 | 2.68k | } |
458 | | |
459 | | Session_Ticket::Session_Ticket(TLS_Data_Reader& reader, |
460 | | uint16_t extension_size) : m_ticket(reader.get_elem<uint8_t, std::vector<uint8_t>>(extension_size)) |
461 | 2.70k | {} |
462 | | |
463 | | SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, |
464 | | uint16_t extension_size) : m_pp(reader.get_range<uint16_t>(2, 0, 65535)) |
465 | 126 | { |
466 | 126 | const std::vector<uint8_t> mki = reader.get_range<uint8_t>(1, 0, 255); |
467 | 126 | |
468 | 126 | if(m_pp.size() * 2 + mki.size() + 3 != extension_size) |
469 | 74 | throw Decoding_Error("Bad encoding for SRTP protection extension"); |
470 | 52 | |
471 | 52 | if(!mki.empty()) |
472 | 3 | throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension"); |
473 | 52 | } |
474 | | |
475 | | std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const |
476 | 0 | { |
477 | 0 | std::vector<uint8_t> buf; |
478 | 0 |
|
479 | 0 | const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2); |
480 | 0 | buf.push_back(get_byte(0, pp_len)); |
481 | 0 | buf.push_back(get_byte(1, pp_len)); |
482 | 0 |
|
483 | 0 | for(uint16_t pp : m_pp) |
484 | 0 | { |
485 | 0 | buf.push_back(get_byte(0, pp)); |
486 | 0 | buf.push_back(get_byte(1, pp)); |
487 | 0 | } |
488 | 0 |
|
489 | 0 | buf.push_back(0); // srtp_mki, always empty here |
490 | 0 |
|
491 | 0 | return buf; |
492 | 0 | } |
493 | | |
494 | | Extended_Master_Secret::Extended_Master_Secret(TLS_Data_Reader&, |
495 | | uint16_t extension_size) |
496 | 6.70k | { |
497 | 6.70k | if(extension_size != 0) |
498 | 44 | throw Decoding_Error("Invalid extended_master_secret extension"); |
499 | 6.70k | } |
500 | | |
501 | | std::vector<uint8_t> Extended_Master_Secret::serialize(Connection_Side /*whoami*/) const |
502 | 9.55k | { |
503 | 9.55k | return std::vector<uint8_t>(); |
504 | 9.55k | } |
505 | | |
506 | | Encrypt_then_MAC::Encrypt_then_MAC(TLS_Data_Reader&, |
507 | | uint16_t extension_size) |
508 | 2.99k | { |
509 | 2.99k | if(extension_size != 0) |
510 | 41 | throw Decoding_Error("Invalid encrypt_then_mac extension"); |
511 | 2.99k | } |
512 | | |
513 | | std::vector<uint8_t> Encrypt_then_MAC::serialize(Connection_Side /*whoami*/) const |
514 | 5.53k | { |
515 | 5.53k | return std::vector<uint8_t>(); |
516 | 5.53k | } |
517 | | |
518 | | std::vector<uint8_t> Certificate_Status_Request::serialize(Connection_Side whoami) const |
519 | 6.16k | { |
520 | 6.16k | std::vector<uint8_t> buf; |
521 | 6.16k | |
522 | 6.16k | if(whoami == Connection_Side::SERVER) |
523 | 923 | return buf; // server reply is empty |
524 | 5.24k | |
525 | 5.24k | /* |
526 | 5.24k | opaque ResponderID<1..2^16-1>; |
527 | 5.24k | opaque Extensions<0..2^16-1>; |
528 | 5.24k | |
529 | 5.24k | CertificateStatusType status_type = ocsp(1) |
530 | 5.24k | ResponderID responder_id_list<0..2^16-1> |
531 | 5.24k | Extensions request_extensions; |
532 | 5.24k | */ |
533 | 5.24k | |
534 | 5.24k | buf.push_back(1); // CertificateStatusType ocsp |
535 | 5.24k | |
536 | 5.24k | buf.push_back(0); |
537 | 5.24k | buf.push_back(0); |
538 | 5.24k | buf.push_back(0); |
539 | 5.24k | buf.push_back(0); |
540 | 5.24k | |
541 | 5.24k | return buf; |
542 | 5.24k | } |
543 | | |
544 | | Certificate_Status_Request::Certificate_Status_Request(TLS_Data_Reader& reader, |
545 | | uint16_t extension_size, |
546 | | Connection_Side from) |
547 | 1.29k | { |
548 | 1.29k | if(from == Connection_Side::SERVER) |
549 | 223 | { |
550 | 223 | if(extension_size != 0) |
551 | 14 | throw Decoding_Error("Server sent non-empty Certificate_Status_Request extension"); |
552 | 1.06k | } |
553 | 1.06k | else if(extension_size > 0) |
554 | 127 | { |
555 | 127 | const uint8_t type = reader.get_byte(); |
556 | 127 | if(type == 1) |
557 | 12 | { |
558 | 12 | const size_t len_resp_id_list = reader.get_uint16_t(); |
559 | 12 | m_ocsp_names = reader.get_fixed<uint8_t>(len_resp_id_list); |
560 | 12 | const size_t len_requ_ext = reader.get_uint16_t(); |
561 | 12 | m_extension_bytes = reader.get_fixed<uint8_t>(len_requ_ext); |
562 | 12 | } |
563 | 115 | else |
564 | 115 | { |
565 | 115 | reader.discard_next(extension_size - 1); |
566 | 115 | } |
567 | 127 | } |
568 | 1.29k | } |
569 | | |
570 | | Certificate_Status_Request::Certificate_Status_Request(const std::vector<uint8_t>& ocsp_responder_ids, |
571 | | const std::vector<std::vector<uint8_t>>& ocsp_key_ids) : |
572 | | m_ocsp_names(ocsp_responder_ids), |
573 | | m_ocsp_keys(ocsp_key_ids) |
574 | 5.24k | { |
575 | 5.24k | } |
576 | | |
577 | | std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const |
578 | 5.24k | { |
579 | 5.24k | std::vector<uint8_t> buf; |
580 | 5.24k | |
581 | 5.24k | if(whoami == Connection_Side::SERVER) |
582 | 0 | { |
583 | 0 | BOTAN_ASSERT_NOMSG(m_versions.size() == 1); |
584 | 0 | buf.push_back(m_versions[0].major_version()); |
585 | 0 | buf.push_back(m_versions[0].minor_version()); |
586 | 0 | } |
587 | 5.24k | else |
588 | 5.24k | { |
589 | 5.24k | BOTAN_ASSERT_NOMSG(m_versions.size() >= 1); |
590 | 5.24k | const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2); |
591 | 5.24k | |
592 | 5.24k | buf.push_back(len); |
593 | 5.24k | |
594 | 5.24k | for(Protocol_Version version : m_versions) |
595 | 5.24k | { |
596 | 5.24k | buf.push_back(get_byte(0, version.major_version())); |
597 | 5.24k | buf.push_back(get_byte(1, version.minor_version())); |
598 | 5.24k | } |
599 | 5.24k | } |
600 | 5.24k | |
601 | 5.24k | return buf; |
602 | 5.24k | } |
603 | | |
604 | | Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) |
605 | 5.24k | { |
606 | 5.24k | if(offer.is_datagram_protocol()) |
607 | 0 | { |
608 | 0 | if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) |
609 | 0 | m_versions.push_back(Protocol_Version::DTLS_V12); |
610 | 0 | #if defined(BOTAN_HAS_TLS_V10) |
611 | 0 | if(offer >= Protocol_Version::DTLS_V10 && policy.allow_dtls10()) |
612 | 0 | m_versions.push_back(Protocol_Version::DTLS_V10); |
613 | 0 | #endif |
614 | 0 | } |
615 | 5.24k | else |
616 | 5.24k | { |
617 | 5.24k | if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) |
618 | 5.24k | m_versions.push_back(Protocol_Version::TLS_V12); |
619 | 5.24k | #if defined(BOTAN_HAS_TLS_V10) |
620 | 5.24k | if(offer >= Protocol_Version::TLS_V11 && policy.allow_tls11()) |
621 | 0 | m_versions.push_back(Protocol_Version::TLS_V11); |
622 | 5.24k | if(offer >= Protocol_Version::TLS_V10 && policy.allow_tls10()) |
623 | 0 | m_versions.push_back(Protocol_Version::TLS_V10); |
624 | 5.24k | #endif |
625 | 5.24k | } |
626 | 5.24k | } |
627 | | |
628 | | Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, |
629 | | uint16_t extension_size, |
630 | | Connection_Side from) |
631 | 128 | { |
632 | 128 | if(from == Connection_Side::SERVER) |
633 | 28 | { |
634 | 28 | if(extension_size != 2) |
635 | 14 | throw Decoding_Error("Server sent invalid supported_versions extension"); |
636 | 14 | m_versions.push_back(Protocol_Version(reader.get_uint16_t())); |
637 | 14 | } |
638 | 100 | else |
639 | 100 | { |
640 | 100 | auto versions = reader.get_range<uint16_t>(1, 1, 127); |
641 | 100 | |
642 | 100 | for(auto v : versions) |
643 | 3.98k | m_versions.push_back(Protocol_Version(v)); |
644 | 100 | |
645 | 100 | if(extension_size != 1+2*versions.size()) |
646 | 73 | throw Decoding_Error("Client sent invalid supported_versions extension"); |
647 | 100 | } |
648 | 128 | } |
649 | | |
650 | | bool Supported_Versions::supports(Protocol_Version version) const |
651 | 0 | { |
652 | 0 | for(auto v : m_versions) |
653 | 0 | if(version == v) |
654 | 0 | return true; |
655 | 0 | return false; |
656 | 0 | } |
657 | | |
658 | | } |
659 | | |
660 | | } |