Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

tls_channel.cpp
Go to the documentation of this file.
1 /*
2 * TLS Channels
3 * (C) 2011,2012,2014,2015,2016 Jack Lloyd
4 * 2016 Matthias Gierlings
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9 #include <botan/tls_channel.h>
10 #include <botan/tls_messages.h>
11 #include <botan/internal/tls_handshake_state.h>
12 #include <botan/internal/tls_record.h>
13 #include <botan/internal/tls_seq_numbers.h>
14 #include <botan/internal/rounding.h>
15 #include <botan/internal/stl_util.h>
16 #include <botan/loadstor.h>
17
18 namespace Botan {
19
20 namespace TLS {
21
22 size_t TLS::Channel::IO_BUF_DEFAULT_SIZE = 10*1024;
23
24 Channel::Channel(Callbacks& callbacks,
25 Session_Manager& session_manager,
26 RandomNumberGenerator& rng,
27 const Policy& policy,
28 bool is_datagram,
29 size_t reserved_io_buffer_size) :
30 m_is_datagram(is_datagram),
31 m_callbacks(callbacks),
32 m_session_manager(session_manager),
33 m_policy(policy),
34 m_rng(rng)
35 {
36 init(reserved_io_buffer_size);
37 }
38
39 Channel::Channel(output_fn out,
40 data_cb app_data_cb,
41 alert_cb alert_cb,
42 handshake_cb hs_cb,
43 handshake_msg_cb hs_msg_cb,
44 Session_Manager& session_manager,
45 RandomNumberGenerator& rng,
46 const Policy& policy,
47 bool is_datagram,
48 size_t io_buf_sz) :
49 m_is_datagram(is_datagram),
50 m_compat_callbacks(new Compat_Callbacks(out, app_data_cb, alert_cb, hs_cb, hs_msg_cb)),
51 m_callbacks(*m_compat_callbacks.get()),
52 m_session_manager(session_manager),
53 m_policy(policy),
54 m_rng(rng)
55 {
56 init(io_buf_sz);
57 }
58
59 void Channel::init(size_t io_buf_sz)
60 {
61 /* epoch 0 is plaintext, thus null cipher state */
62 m_write_cipher_states[0] = nullptr;
63 m_read_cipher_states[0] = nullptr;
64
65 m_writebuf.reserve(io_buf_sz);
66 m_readbuf.reserve(io_buf_sz);
67 }
68
69 void Channel::reset_state()
70 {
71 m_active_state.reset();
72 m_pending_state.reset();
73 m_readbuf.clear();
74 m_write_cipher_states.clear();
75 m_read_cipher_states.clear();
76 }
77
78 Channel::~Channel()
79 {
80 // So unique_ptr destructors run correctly
81 }
82
83 Connection_Sequence_Numbers& Channel::sequence_numbers() const
84 {
85 BOTAN_ASSERT(m_sequence_numbers, "Have a sequence numbers object");
86 return *m_sequence_numbers;
87 }
88
89 std::shared_ptr<Connection_Cipher_State> Channel::read_cipher_state_epoch(uint16_t epoch) const
90 {
91 auto i = m_read_cipher_states.find(epoch);
92 if(i == m_read_cipher_states.end())
93 throw Internal_Error("TLS::Channel No read cipherstate for epoch " + std::to_string(epoch));
94 return i->second;
95 }
96
97 std::shared_ptr<Connection_Cipher_State> Channel::write_cipher_state_epoch(uint16_t epoch) const
98 {
99 auto i = m_write_cipher_states.find(epoch);
100 if(i == m_write_cipher_states.end())
101 throw Internal_Error("TLS::Channel No write cipherstate for epoch " + std::to_string(epoch));
102 return i->second;
103 }
104
105 std::vector<X509_Certificate> Channel::peer_cert_chain() const
106 {
107 if(auto active = active_state())
108 return get_peer_cert_chain(*active);
109 return std::vector<X509_Certificate>();
110 }
111
112 Handshake_State& Channel::create_handshake_state(Protocol_Version version)
113 {
114 if(pending_state())
115 throw Internal_Error("create_handshake_state called during handshake");
116
117 if(auto active = active_state())
118 {
119 Protocol_Version active_version = active->version();
120
121 if(active_version.is_datagram_protocol() != version.is_datagram_protocol())
122 throw Exception("Active state using version " +
123 active_version.to_string() +
124 " cannot change to " +
125 version.to_string() +
126 " in pending");
127 }
128
129 if(!m_sequence_numbers)
130 {
131 if(version.is_datagram_protocol())
132 m_sequence_numbers.reset(new Datagram_Sequence_Numbers);
133 else
134 m_sequence_numbers.reset(new Stream_Sequence_Numbers);
135 }
136
137 using namespace std::placeholders;
138
139 std::unique_ptr<Handshake_IO> io;
140 if(version.is_datagram_protocol())
141 {
142 io.reset(new Datagram_Handshake_IO(
143 std::bind(&Channel::send_record_under_epoch, this, _1, _2, _3),
144 sequence_numbers(),
145 static_cast<uint16_t>(m_policy.dtls_default_mtu()),
146 m_policy.dtls_initial_timeout(),
147 m_policy.dtls_maximum_timeout()));
148 }
149 else
150 {
151 io.reset(new Stream_Handshake_IO(std::bind(&Channel::send_record, this, _1, _2)));
152 }
153
154 m_pending_state.reset(new_handshake_state(io.release()));
155
156 if(auto active = active_state())
157 m_pending_state->set_version(active->version());
158
159 return *m_pending_state.get();
160 }
161
162 bool Channel::timeout_check()
163 {
164 if(m_pending_state)
165 return m_pending_state->handshake_io().timeout_check();
166
167 //FIXME: scan cipher suites and remove epochs older than 2*MSL
168 return false;
169 }
170
171 void Channel::renegotiate(bool force_full_renegotiation)
172 {
173 if(pending_state()) // currently in handshake?
174 return;
175
176 if(auto active = active_state())
177 initiate_handshake(create_handshake_state(active->version()),
178 force_full_renegotiation);
179 else
180 throw Exception("Cannot renegotiate on inactive connection");
181 }
182
183 void Channel::change_cipher_spec_reader(Connection_Side side)
184 {
185 auto pending = pending_state();
186
187 BOTAN_ASSERT(pending && pending->server_hello(),
188 "Have received server hello");
189
190 if(pending->server_hello()->compression_method() != NO_COMPRESSION)
191 throw Internal_Error("Negotiated unknown compression algorithm");
192
193 sequence_numbers().new_read_cipher_state();
194
195 const uint16_t epoch = sequence_numbers().current_read_epoch();
196
197 BOTAN_ASSERT(m_read_cipher_states.count(epoch) == 0,
198 "No read cipher state currently set for next epoch");
199
200 // flip side as we are reading
201 std::shared_ptr<Connection_Cipher_State> read_state(
202 new Connection_Cipher_State(pending->version(),
203 (side == CLIENT) ? SERVER : CLIENT,
204 false,
205 pending->ciphersuite(),
206 pending->session_keys(),
207 pending->server_hello()->supports_encrypt_then_mac()));
208
209 m_read_cipher_states[epoch] = read_state;
210 }
211
212 void Channel::change_cipher_spec_writer(Connection_Side side)
213 {
214 auto pending = pending_state();
215
216 BOTAN_ASSERT(pending && pending->server_hello(),
217 "Have received server hello");
218
219 if(pending->server_hello()->compression_method() != NO_COMPRESSION)
220 throw Internal_Error("Negotiated unknown compression algorithm");
221
222 sequence_numbers().new_write_cipher_state();
223
224 const uint16_t epoch = sequence_numbers().current_write_epoch();
225
226 BOTAN_ASSERT(m_write_cipher_states.count(epoch) == 0,
227 "No write cipher state currently set for next epoch");
228
229 std::shared_ptr<Connection_Cipher_State> write_state(
230 new Connection_Cipher_State(pending->version(),
231 side,
232 true,
233 pending->ciphersuite(),
234 pending->session_keys(),
235 pending->server_hello()->supports_encrypt_then_mac()));
236
237 m_write_cipher_states[epoch] = write_state;
238 }
239
240 bool Channel::is_active() const
241 {
242 return (active_state() != nullptr);
243 }
244
245 bool Channel::is_closed() const
246 {
247 if(active_state() || pending_state())
248 return false;
249
250 /*
251 * If no active or pending state, then either we had a connection
252 * and it has been closed, or we are a server which has never
253 * received a connection. This case is detectable by also lacking
254 * m_sequence_numbers
255 */
256 return (m_sequence_numbers != nullptr);
257 }
258
259 void Channel::activate_session()
260 {
261 std::swap(m_active_state, m_pending_state);
262 m_pending_state.reset();
263
264 if(!m_active_state->version().is_datagram_protocol())
265 {
266 // TLS is easy just remove all but the current state
267 const uint16_t current_epoch = sequence_numbers().current_write_epoch();
268
269 const auto not_current_epoch =
270 [current_epoch](uint16_t epoch) { return (epoch != current_epoch); };
271
272 map_remove_if(not_current_epoch, m_write_cipher_states);
273 map_remove_if(not_current_epoch, m_read_cipher_states);
274 }
275
276 callbacks().tls_session_activated();
277 }
278
279 size_t Channel::received_data(const std::vector<uint8_t>& buf)
280 {
281 return this->received_data(buf.data(), buf.size());
282 }
283
284 size_t Channel::received_data(const uint8_t input[], size_t input_size)
285 {
286 try
287 {
288 while(!is_closed() && input_size)
289 {
290 secure_vector<uint8_t> record_data;
291 uint64_t record_sequence = 0;
292 Record_Type record_type = NO_RECORD;
293 Protocol_Version record_version;
294
295 size_t consumed = 0;
296
297 Record_Raw_Input raw_input(input, input_size, consumed, m_is_datagram);
298 Record record(record_data, &record_sequence, &record_version, &record_type);
299 const size_t needed =
300 read_record(m_readbuf,
301 raw_input,
302 record,
303 m_sequence_numbers.get(),
304 std::bind(&TLS::Channel::read_cipher_state_epoch, this,
305 std::placeholders::_1));
306
307 BOTAN_ASSERT(consumed > 0, "Got to eat something");
308
309 BOTAN_ASSERT(consumed <= input_size,
310 "Record reader consumed sane amount");
311
312 input += consumed;
313 input_size -= consumed;
314
315 BOTAN_ASSERT(input_size == 0 || needed == 0,
316 "Got a full record or consumed all input");
317
318 if(input_size == 0 && needed != 0)
319 return needed; // need more data to complete record
320
321 if(record_data.size() > MAX_PLAINTEXT_SIZE)
322 throw TLS_Exception(Alert::RECORD_OVERFLOW,
323 "TLS plaintext record is larger than allowed maximum");
324
325 if(record_type == HANDSHAKE || record_type == CHANGE_CIPHER_SPEC)
326 {
327 process_handshake_ccs(record_data, record_sequence, record_type, record_version);
328 }
329 else if(record_type == APPLICATION_DATA)
330 {
331 process_application_data(record_sequence, record_data);
332 }
333 else if(record_type == ALERT)
334 {
335 process_alert(record_data);
336 }
337 else if(record_type != NO_RECORD)
338 throw Unexpected_Message("Unexpected record type " +
339 std::to_string(record_type) +
340 " from counterparty");
341 }
342
343 return 0; // on a record boundary
344 }
345 catch(TLS_Exception& e)
346 {
347 send_fatal_alert(e.type());
348 throw;
349 }
350 catch(Integrity_Failure&)
351 {
352 send_fatal_alert(Alert::BAD_RECORD_MAC);
353 throw;
354 }
355 catch(Decoding_Error&)
356 {
357 send_fatal_alert(Alert::DECODE_ERROR);
358 throw;
359 }
360 catch(...)
361 {
362 send_fatal_alert(Alert::INTERNAL_ERROR);
363 throw;
364 }
365 }
366
367 void Channel::process_handshake_ccs(const secure_vector<uint8_t>& record,
368 uint64_t record_sequence,
369 Record_Type record_type,
370 Protocol_Version record_version)
371 {
372 if(!m_pending_state)
373 {
374 // No pending handshake, possibly new:
375 if(record_version.is_datagram_protocol())
376 {
377 if(m_sequence_numbers)
378 {
379 /*
380 * Might be a peer retransmit under epoch - 1 in which
381 * case we must retransmit last flight
382 */
383 sequence_numbers().read_accept(record_sequence);
384
385 const uint16_t epoch = record_sequence >> 48;
386
387 if(epoch == sequence_numbers().current_read_epoch())
388 {
389 create_handshake_state(record_version);
390 }
391 else if(epoch == sequence_numbers().current_read_epoch() - 1)
392 {
393 BOTAN_ASSERT(m_active_state, "Have active state here");
394 m_active_state->handshake_io().add_record(unlock(record),
395 record_type,
396 record_sequence);
397 }
398 }
399 else if(record_sequence == 0)
400 {
401 create_handshake_state(record_version);
402 }
403 }
404 else
405 {
406 create_handshake_state(record_version);
407 }
408 }
409
410 // May have been created in above conditional
411 if(m_pending_state)
412 {
413 m_pending_state->handshake_io().add_record(unlock(record),
414 record_type,
415 record_sequence);
416
417 while(auto pending = m_pending_state.get())
418 {
419 auto msg = pending->get_next_handshake_msg();
420
421 if(msg.first == HANDSHAKE_NONE) // no full handshake yet
422 break;
423
424 process_handshake_msg(active_state(), *pending,
425 msg.first, msg.second);
426 }
427 }
428 }
429
430 void Channel::process_application_data(uint64_t seq_no, const secure_vector<uint8_t>& record)
431 {
432 if(!active_state())
433 throw Unexpected_Message("Application data before handshake done");
434
435 /*
436 * OpenSSL among others sends empty records in versions
437 * before TLS v1.1 in order to randomize the IV of the
438 * following record. Avoid spurious callbacks.
439 */
440 if(record.size() > 0)
441 callbacks().tls_record_received(seq_no, record.data(), record.size());
442 }
443
444 void Channel::process_alert(const secure_vector<uint8_t>& record)
445 {
446 Alert alert_msg(record);
447
448 if(alert_msg.type() == Alert::NO_RENEGOTIATION)
449 m_pending_state.reset();
450
451 callbacks().tls_alert(alert_msg);
452
453 if(alert_msg.is_fatal())
454 {
455 if(auto active = active_state())
456 m_session_manager.remove_entry(active->server_hello()->session_id());
457 }
458
459 if(alert_msg.type() == Alert::CLOSE_NOTIFY)
460 send_warning_alert(Alert::CLOSE_NOTIFY); // reply in kind
461
462 if(alert_msg.type() == Alert::CLOSE_NOTIFY || alert_msg.is_fatal())
463 {
464 reset_state();
465 }
466 }
467
468
469 void Channel::write_record(Connection_Cipher_State* cipher_state, uint16_t epoch,
470 uint8_t record_type, const uint8_t input[], size_t length)
471 {
472 BOTAN_ASSERT(m_pending_state || m_active_state, "Some connection state exists");
473
474 Protocol_Version record_version =
475 (m_pending_state) ? (m_pending_state->version()) : (m_active_state->version());
476
477 Record_Message record_message(record_type, 0, input, length);
478
479 TLS::write_record(m_writebuf,
480 record_message,
481 record_version,
482 sequence_numbers().next_write_sequence(epoch),
483 cipher_state,
484 m_rng);
485
486 callbacks().tls_emit_data(m_writebuf.data(), m_writebuf.size());
487 }
488
489 void Channel::send_record_array(uint16_t epoch, uint8_t type, const uint8_t input[], size_t length)
490 {
491 if(length == 0)
492 return;
493
494 /*
495 * In versions without an explicit IV field (only TLS v1.0 now that
496 * SSLv3 has been removed) send a single byte record first to randomize
497 * the following (implicit) IV of the following record.
498 *
499 * This isn't needed in TLS v1.1 or higher.
500 *
501 * An empty record also works but apparently some implementations do
502 * not like this (https://bugzilla.mozilla.org/show_bug.cgi?id=665814)
503 *
504 * See http://www.openssl.org/~bodo/tls-cbc.txt for background.
505 */
506
507 auto cipher_state = write_cipher_state_epoch(epoch);
508
509 if(type == APPLICATION_DATA && m_active_state->version().supports_explicit_cbc_ivs() == false)
510 {
511 write_record(cipher_state.get(), epoch, type, input, 1);
512 input += 1;
513 length -= 1;
514 }
515
516 while(length)
517 {
518 const size_t sending = std::min<size_t>(length, MAX_PLAINTEXT_SIZE);
519 write_record(cipher_state.get(), epoch, type, input, sending);
520
521 input += sending;
522 length -= sending;
523 }
524 }
525
526 void Channel::send_record(uint8_t record_type, const std::vector<uint8_t>& record)
527 {
528 send_record_array(sequence_numbers().current_write_epoch(),
529 record_type, record.data(), record.size());
530 }
531
532 void Channel::send_record_under_epoch(uint16_t epoch, uint8_t record_type,
533 const std::vector<uint8_t>& record)
534 {
535 send_record_array(epoch, record_type, record.data(), record.size());
536 }
537
538 void Channel::send(const uint8_t buf[], size_t buf_size)
539 {
540 if(!is_active())
541 throw Exception("Data cannot be sent on inactive TLS connection");
542
543 send_record_array(sequence_numbers().current_write_epoch(),
544 APPLICATION_DATA, buf, buf_size);
545 }
546
547 void Channel::send(const std::string& string)
548 {
549 this->send(reinterpret_cast<const uint8_t*>(string.c_str()), string.size());
550 }
551
552 void Channel::send_alert(const Alert& alert)
553 {
554 if(alert.is_valid() && !is_closed())
555 {
556 try
557 {
558 send_record(ALERT, alert.serialize());
559 }
560 catch(...) { /* swallow it */ }
561 }
562
563 if(alert.type() == Alert::NO_RENEGOTIATION)
564 m_pending_state.reset();
565
566 if(alert.is_fatal())
567 if(auto active = active_state())
568 m_session_manager.remove_entry(active->server_hello()->session_id());
569
570 if(alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal())
571 reset_state();
572 }
573
574 void Channel::secure_renegotiation_check(const Client_Hello* client_hello)
575 {
576 const bool secure_renegotiation = client_hello->secure_renegotiation();
577
578 if(auto active = active_state())
579 {
580 const bool active_sr = active->client_hello()->secure_renegotiation();
581
582 if(active_sr != secure_renegotiation)
583 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
584 "Client changed its mind about secure renegotiation");
585 }
586
587 if(secure_renegotiation)
588 {
589 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
590
591 if(data != secure_renegotiation_data_for_client_hello())
592 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
593 "Client sent bad values for secure renegotiation");
594 }
595 }
596
597 void Channel::secure_renegotiation_check(const Server_Hello* server_hello)
598 {
599 const bool secure_renegotiation = server_hello->secure_renegotiation();
600
601 if(auto active = active_state())
602 {
603 const bool active_sr = active->client_hello()->secure_renegotiation();
604
605 if(active_sr != secure_renegotiation)
606 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
607 "Server changed its mind about secure renegotiation");
608 }
609
610 if(secure_renegotiation)
611 {
612 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
613
614 if(data != secure_renegotiation_data_for_server_hello())
615 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
616 "Server sent bad values for secure renegotiation");
617 }
618 }
619
620 std::vector<uint8_t> Channel::secure_renegotiation_data_for_client_hello() const
621 {
622 if(auto active = active_state())
623 return active->client_finished()->verify_data();
624 return std::vector<uint8_t>();
625 }
626
627 std::vector<uint8_t> Channel::secure_renegotiation_data_for_server_hello() const
628 {
629 if(auto active = active_state())
630 {
631 std::vector<uint8_t> buf = active->client_finished()->verify_data();
632 buf += active->server_finished()->verify_data();
633 return buf;
634 }
635
636 return std::vector<uint8_t>();
637 }
638
639 bool Channel::secure_renegotiation_supported() const
640 {
641 if(auto active = active_state())
642 return active->server_hello()->secure_renegotiation();
643
644 if(auto pending = pending_state())
645 if(auto hello = pending->server_hello())
646 return hello->secure_renegotiation();
647
648 return false;
649 }
650
651 SymmetricKey Channel::key_material_export(const std::string& label,
652 const std::string& context,
653 size_t length) const
654 {
655 if(auto active = active_state())
656 {
657 std::unique_ptr<KDF> prf(active->protocol_specific_prf());
658
659 const secure_vector<uint8_t>& master_secret =
660 active->session_keys().master_secret();
661
662 std::vector<uint8_t> salt;
663 salt += active->client_hello()->random();
664 salt += active->server_hello()->random();
665
666 if(context != "")
667 {
668 size_t context_size = context.length();
669 if(context_size > 0xFFFF)
670 throw Exception("key_material_export context is too long");
671 salt.push_back(get_byte(0, static_cast<uint16_t>(context_size)));
672 salt.push_back(get_byte(1, static_cast<uint16_t>(context_size)));
673 salt += to_byte_vector(context);
674 }
675
676 return prf->derive_key(length, master_secret, salt, to_byte_vector(label));
677 }
678 else
679 throw Exception("Channel::key_material_export connection not active");
680 }
681
682 }
683
684 }
Botan::TLS::Channel::key_material_export
SymmetricKey key_material_export(const std::string &label, const std::string &context, size_t length) const
Definition: tls_channel.cpp:651
placeholders
Botan::TLS::Session_Manager
Definition: tls_session_manager.h:29
Botan::TLS::Channel::secure_renegotiation_data_for_server_hello
std::vector< uint8_t > secure_renegotiation_data_for_server_hello() const
Definition: tls_channel.cpp:627
Botan::TLS::Connection_Cipher_State
Definition: tls_record.h:32
Botan::TLS::Channel::get_peer_cert_chain
virtual std::vector< X509_Certificate > get_peer_cert_chain(const Handshake_State &state) const =0
Botan::TLS::Channel::peer_cert_chain
std::vector< X509_Certificate > peer_cert_chain() const
Definition: tls_channel.cpp:105
Botan::TLS::Channel::callbacks
Callbacks & callbacks() const
Definition: tls_channel.h:241
Botan::TLS::HANDSHAKE_NONE
Definition: tls_magic.h:56
Botan::TLS::ALERT
Definition: tls_magic.h:31
Botan::TLS::NO_COMPRESSION
Definition: tls_magic.h:62
Botan::TLS::Session_Manager::remove_entry
virtual void remove_entry(const std::vector< uint8_t > &session_id)=0
Botan::TLS::Channel::secure_renegotiation_data_for_client_hello
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const
Definition: tls_channel.cpp:620
Botan::TLS::Server_Hello
Definition: tls_messages.h:255
Botan::TLS::Stream_Handshake_IO
Definition: tls_handshake_io.h:65
Botan::Exception
Definition: exceptn.h:21
Botan::OctetString
Definition: symkey.h:19
Botan::TLS::Record_Raw_Input
Definition: tls_record.h:124
Botan::TLS::Datagram_Handshake_IO
Definition: tls_handshake_io.h:96
Botan::RandomNumberGenerator
Definition: rng.h:25
Botan::TLS::MAX_PLAINTEXT_SIZE
Definition: tls_magic.h:22
Botan::TLS::Channel::alert_cb
std::function< void(Alert, const uint8_t[], size_t)> alert_cb
Definition: tls_channel.h:41
Botan::TLS::Channel::change_cipher_spec_reader
void change_cipher_spec_reader(Connection_Side side)
Definition: tls_channel.cpp:183
Botan::TLS::Alert::is_valid
bool is_valid() const
Definition: tls_alert.h:69
Botan::TLS::read_record
size_t read_record(secure_vector< uint8_t > &readbuf, Record_Raw_Input &raw_input, Record &rec, Connection_Sequence_Numbers *sequence_numbers, get_cipherstate_fn get_cipherstate)
Definition: tls_record.cpp:494
Botan::Integrity_Failure
Definition: exceptn.h:198
Botan::TLS::Channel::change_cipher_spec_writer
void change_cipher_spec_writer(Connection_Side side)
Definition: tls_channel.cpp:212
Botan::Internal_Error
Definition: exceptn.h:88
Botan::TLS::Channel::send_warning_alert
void send_warning_alert(Alert::Type type)
Definition: tls_channel.h:140
Botan::TLS::Channel::output_fn
std::function< void(const uint8_t[], size_t)> output_fn
Definition: tls_channel.h:39
Botan::TLS::Protocol_Version::to_string
std::string to_string() const
Definition: tls_version.cpp:16
Botan::TLS::Callbacks::tls_alert
virtual void tls_alert(Alert alert)=0
Botan::TLS::Channel::create_handshake_state
Handshake_State & create_handshake_state(Protocol_Version version)
Definition: tls_channel.cpp:112
Botan::TLS::Alert::INTERNAL_ERROR
Definition: tls_alert.h:49
Botan::TLS::APPLICATION_DATA
Definition: tls_magic.h:33
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
Botan::TLS::Protocol_Version
Definition: tls_version.h:21
type
MechanismType type
Definition: p11_mechanism.cpp:43
Botan::OctetString::length
size_t length() const
Definition: symkey.h:25
Botan::TLS::Connection_Side
Connection_Side
Definition: tls_magic.h:27
Botan::TLS::Callbacks
Definition: tls_callbacks.h:35
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
Botan::TLS::Channel::is_closed
bool is_closed() const
Definition: tls_channel.cpp:245
Botan::TLS::Channel::send_alert
void send_alert(const Alert &alert)
Definition: tls_channel.cpp:552
Botan::TLS::Client_Hello::renegotiation_info
std::vector< uint8_t > renegotiation_info() const
Definition: tls_messages.h:158
Botan::TLS::Alert::HANDSHAKE_FAILURE
Definition: tls_alert.h:34
Botan::TLS::Stream_Sequence_Numbers
Definition: tls_seq_numbers.h:35
Botan::TLS::Callbacks::tls_record_received
virtual void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size)=0
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::TLS::Connection_Sequence_Numbers::new_read_cipher_state
virtual void new_read_cipher_state()=0
Botan::TLS::Datagram_Sequence_Numbers
Definition: tls_seq_numbers.h:56
Botan::TLS::Channel::handshake_cb
std::function< bool(const Session &)> handshake_cb
Definition: tls_channel.h:42
Botan::TLS::Channel::send
void send(const uint8_t buf[], size_t buf_size)
Definition: tls_channel.cpp:538
Botan::TLS::Channel::secure_renegotiation_supported
bool secure_renegotiation_supported() const
Definition: tls_channel.cpp:639
Botan::TLS::Channel::IO_BUF_DEFAULT_SIZE
static size_t IO_BUF_DEFAULT_SIZE
Definition: tls_channel.h:44
Botan::TLS::CLIENT
Definition: tls_magic.h:27
Botan::TLS::Alert::DECODE_ERROR
Definition: tls_alert.h:44
Botan::TLS::Channel::new_handshake_state
virtual Handshake_State * new_handshake_state(class Handshake_IO *io)=0
Botan::TLS::SERVER
Definition: tls_magic.h:27
Botan::Decoding_Error
Definition: exceptn.h:189
Botan::TLS::Compat_Callbacks
Definition: tls_callbacks.h:202
Botan
Definition: alg_id.cpp:13
Botan::TLS::Connection_Sequence_Numbers
Definition: tls_seq_numbers.h:17
Botan::to_byte_vector
std::vector< uint8_t > to_byte_vector(const std::string &s)
Definition: stl_util.h:20
Botan::TLS::Record_Type
Record_Type
Definition: tls_magic.h:29
Botan::TLS::Channel::send_fatal_alert
void send_fatal_alert(Alert::Type type)
Definition: tls_channel.h:145
Botan::TLS::Channel::secure_renegotiation_check
void secure_renegotiation_check(const Client_Hello *client_hello)
Definition: tls_channel.cpp:574
m_rng
RandomNumberGenerator & m_rng
Definition: ecdh.cpp:52
Botan::TLS::Channel::received_data
size_t received_data(const uint8_t buf[], size_t buf_size)
Definition: tls_channel.cpp:284
Botan::TLS::CHANGE_CIPHER_SPEC
Definition: tls_magic.h:30
Botan::TLS::Channel::data_cb
std::function< void(const uint8_t[], size_t)> data_cb
Definition: tls_channel.h:40
Botan::TLS::Callbacks::tls_session_activated
virtual void tls_session_activated()
Definition: tls_callbacks.h:92
Botan::unlock
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
Botan::TLS::Policy
Definition: tls_policy.h:26
Botan::map_remove_if
void map_remove_if(Pred pred, T &assoc)
Definition: stl_util.h:96
Botan::TLS::Channel::Channel
Channel(Callbacks &callbacks, Session_Manager &session_manager, RandomNumberGenerator &rng, const Policy &policy, bool is_datagram, size_t io_buf_sz=IO_BUF_DEFAULT_SIZE)
Definition: tls_channel.cpp:24
Botan::TLS::NO_RECORD
Definition: tls_magic.h:35
Botan::TLS::Alert::RECORD_OVERFLOW
Definition: tls_alert.h:32
Botan::TLS::Connection_Sequence_Numbers::current_write_epoch
virtual uint16_t current_write_epoch() const =0
Botan::TLS::Alert::type
Type type() const
Definition: tls_alert.h:79
Botan::TLS::Alert::CLOSE_NOTIFY
Definition: tls_alert.h:28
Botan::TLS::Callbacks::tls_emit_data
virtual void tls_emit_data(const uint8_t data[], size_t size)=0
Botan::TLS::Channel::renegotiate
void renegotiate(bool force_full_renegotiation=false)
Definition: tls_channel.cpp:171
Botan::TLS::Handshake_State
Definition: tls_handshake_state.h:47
Botan::TLS::write_record
void write_record(secure_vector< uint8_t > &output, Record_Message msg, Protocol_Version version, uint64_t seq, Connection_Cipher_State *cs, RandomNumberGenerator &rng)
Definition: tls_record.cpp:213
Botan::get_byte
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:47
Botan::TLS::Server_Hello::secure_renegotiation
bool secure_renegotiation() const
Definition: tls_messages.h:299
Botan::TLS::Server_Hello::renegotiation_info
std::vector< uint8_t > renegotiation_info() const
Definition: tls_messages.h:304
Botan::TLS::Connection_Sequence_Numbers::read_accept
virtual void read_accept(uint64_t seq)=0
Botan::TLS::Alert::NO_RENEGOTIATION
Definition: tls_alert.h:52
Botan::TLS::Record
Definition: tls_record.h:75
Botan::TLS::Channel::process_handshake_msg
virtual void process_handshake_msg(const Handshake_State *active_state, Handshake_State &pending_state, Handshake_Type type, const std::vector< uint8_t > &contents)=0
Botan::TLS::Alert
Definition: tls_alert.h:21
Botan::TLS::Channel::activate_session
void activate_session()
Definition: tls_channel.cpp:259
Botan::TLS::Connection_Sequence_Numbers::current_read_epoch
virtual uint16_t current_read_epoch() const =0
Botan::TLS::TLS_Exception::type
Alert::Type type() const
Definition: tls_exceptn.h:24
Botan::TLS::Channel::timeout_check
bool timeout_check()
Definition: tls_channel.cpp:162
Botan::TLS::Alert::is_fatal
bool is_fatal() const
Definition: tls_alert.h:74
Botan::TLS::Connection_Sequence_Numbers::new_write_cipher_state
virtual void new_write_cipher_state()=0
Botan::TLS::Protocol_Version::is_datagram_protocol
bool is_datagram_protocol() const
Definition: tls_version.cpp:34
Botan::TLS::Unexpected_Message
Definition: tls_exceptn.h:37
Botan::TLS::Client_Hello::secure_renegotiation
bool secure_renegotiation() const
Definition: tls_messages.h:153
Botan::TLS::Channel::~Channel
virtual ~Channel()
Definition: tls_channel.cpp:78
Botan::TLS::HANDSHAKE
Definition: tls_magic.h:32
Botan::TLS::TLS_Exception
Definition: tls_exceptn.h:21
Botan::TLS::Channel::is_active
bool is_active() const
Definition: tls_channel.cpp:240
Botan::TLS::Channel::handshake_msg_cb
std::function< void(const Handshake_Message &)> handshake_msg_cb
Definition: tls_channel.h:43
Botan::TLS::Alert::serialize
std::vector< uint8_t > serialize() const
Definition: tls_alert.cpp:31
Botan::TLS::Channel::initiate_handshake
virtual void initiate_handshake(Handshake_State &state, bool force_full_renegotiation)=0
Botan::TLS::Alert::BAD_RECORD_MAC
Definition: tls_alert.h:30
Botan::TLS::Client_Hello
Definition: tls_messages.h:67