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