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