Botan  2.15.0
Crypto and TLS for C++11
tls_client.cpp
Go to the documentation of this file.
1 /*
2 * TLS Client
3 * (C) 2004-2011,2012,2015,2016 Jack Lloyd
4 * 2016 Matthias Gierlings
5 * 2017 Harry Reimann, Rohde & Schwarz Cybersecurity
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9 
10 #include <botan/tls_client.h>
11 #include <botan/tls_messages.h>
12 #include <botan/internal/tls_handshake_state.h>
13 #include <botan/internal/stl_util.h>
14 #include <iterator>
15 #include <sstream>
16 
17 namespace Botan {
18 
19 namespace TLS {
20 
21 namespace {
22 
23 class Client_Handshake_State final : public Handshake_State
24  {
25  public:
26  Client_Handshake_State(Handshake_IO* io, Callbacks& cb) :
27  Handshake_State(io, cb),
28  m_is_reneg(false)
29  {}
30 
31  const Public_Key& get_server_public_key() const
32  {
33  BOTAN_ASSERT(server_public_key, "Server sent us a certificate");
34  return *server_public_key.get();
35  }
36 
37  bool is_a_resumption() const { return (resumed_session != nullptr); }
38 
39  bool is_a_renegotiation() const { return m_is_reneg; }
40 
41  const secure_vector<uint8_t>& resume_master_secret() const
42  {
43  BOTAN_STATE_CHECK(is_a_resumption());
44  return resumed_session->master_secret();
45  }
46 
47  const std::vector<X509_Certificate>& resume_peer_certs() const
48  {
49  BOTAN_STATE_CHECK(is_a_resumption());
50  return resumed_session->peer_certs();
51  }
52 
53  std::unique_ptr<Public_Key> server_public_key;
54  // Used during session resumption
55  std::unique_ptr<Session> resumed_session;
56  bool m_is_reneg = false;
57  };
58 
59 }
60 
61 /*
62 * TLS Client Constructor
63 */
65  Session_Manager& session_manager,
66  Credentials_Manager& creds,
67  const Policy& policy,
69  const Server_Information& info,
70  const Protocol_Version& offer_version,
71  const std::vector<std::string>& next_protos,
72  size_t io_buf_sz) :
73  Channel(callbacks, session_manager, rng, policy,
74  false, offer_version.is_datagram_protocol(), io_buf_sz),
75  m_creds(creds),
76  m_info(info)
77  {
78  init(offer_version, next_protos);
79  }
80 
81 Client::Client(output_fn data_output_fn,
82  data_cb proc_cb,
83  alert_cb recv_alert_cb,
84  handshake_cb hs_cb,
85  Session_Manager& session_manager,
86  Credentials_Manager& creds,
87  const Policy& policy,
89  const Server_Information& info,
90  const Protocol_Version& offer_version,
91  const std::vector<std::string>& next_protos,
92  size_t io_buf_sz) :
93  Channel(data_output_fn, proc_cb, recv_alert_cb, hs_cb, Channel::handshake_msg_cb(),
94  session_manager, rng, policy, false, offer_version.is_datagram_protocol(), io_buf_sz),
95  m_creds(creds),
96  m_info(info)
97  {
98  init(offer_version, next_protos);
99  }
100 
101 Client::Client(output_fn data_output_fn,
102  data_cb proc_cb,
103  alert_cb recv_alert_cb,
104  handshake_cb hs_cb,
105  handshake_msg_cb hs_msg_cb,
106  Session_Manager& session_manager,
107  Credentials_Manager& creds,
108  const Policy& policy,
110  const Server_Information& info,
111  const Protocol_Version& offer_version,
112  const std::vector<std::string>& next_protos) :
113  Channel(data_output_fn, proc_cb, recv_alert_cb, hs_cb, hs_msg_cb,
114  session_manager, rng, policy, false, offer_version.is_datagram_protocol()),
115  m_creds(creds),
116  m_info(info)
117  {
118  init(offer_version, next_protos);
119  }
120 
121 void Client::init(const Protocol_Version& protocol_version,
122  const std::vector<std::string>& next_protocols)
123  {
124  const std::string srp_identifier = m_creds.srp_identifier("tls-client", m_info.hostname());
125 
126  Handshake_State& state = create_handshake_state(protocol_version);
127  send_client_hello(state, false, protocol_version,
128  srp_identifier, next_protocols);
129  }
130 
131 Handshake_State* Client::new_handshake_state(Handshake_IO* io)
132  {
133  return new Client_Handshake_State(io, callbacks());
134  }
135 
136 std::vector<X509_Certificate>
137 Client::get_peer_cert_chain(const Handshake_State& state) const
138  {
139  const Client_Handshake_State& cstate = dynamic_cast<const Client_Handshake_State&>(state);
140 
141  if(cstate.is_a_resumption())
142  return cstate.resume_peer_certs();
143 
144  if(state.server_certs())
145  return state.server_certs()->cert_chain();
146  return std::vector<X509_Certificate>();
147  }
148 
149 /*
150 * Send a new client hello to renegotiate
151 */
152 void Client::initiate_handshake(Handshake_State& state,
153  bool force_full_renegotiation)
154  {
155  send_client_hello(state, force_full_renegotiation,
156  policy().latest_supported_version(state.version().is_datagram_protocol()));
157  }
158 
159 void Client::send_client_hello(Handshake_State& state_base,
160  bool force_full_renegotiation,
161  Protocol_Version version,
162  const std::string& srp_identifier,
163  const std::vector<std::string>& next_protocols)
164  {
165  Client_Handshake_State& state = dynamic_cast<Client_Handshake_State&>(state_base);
166 
167  if(state.version().is_datagram_protocol())
168  state.set_expected_next(HELLO_VERIFY_REQUEST); // optional
169  state.set_expected_next(SERVER_HELLO);
170 
171  if(!force_full_renegotiation && !m_info.empty())
172  {
173  std::unique_ptr<Session> session_info(new Session);;
174  if(session_manager().load_from_server_info(m_info, *session_info))
175  {
176  /*
177  Ensure that the session protocol cipher and version are acceptable
178  If not skip the resume and establish a new session
179  */
180  const bool exact_version = session_info->version() == version;
181  const bool ok_version =
182  (session_info->version().is_datagram_protocol() == version.is_datagram_protocol()) &&
183  policy().acceptable_protocol_version(session_info->version());
184 
185  const bool session_version_ok = policy().only_resume_with_exact_version() ? exact_version : ok_version;
186 
187  if(policy().acceptable_ciphersuite(session_info->ciphersuite()) && session_version_ok)
188  {
189  if(srp_identifier == "" || session_info->srp_identifier() == srp_identifier)
190  {
191  state.client_hello(
192  new Client_Hello(state.handshake_io(),
193  state.hash(),
194  policy(),
195  callbacks(),
196  rng(),
198  *session_info,
199  next_protocols));
200 
201  state.resumed_session = std::move(session_info);
202  }
203  }
204  }
205  }
206 
207  if(!state.client_hello()) // not resuming
208  {
209  Client_Hello::Settings client_settings(version, m_info.hostname(), srp_identifier);
210  state.client_hello(new Client_Hello(
211  state.handshake_io(),
212  state.hash(),
213  policy(),
214  callbacks(),
215  rng(),
217  client_settings,
218  next_protocols));
219  }
220 
221  secure_renegotiation_check(state.client_hello());
222  }
223 
224 namespace {
225 
226 bool key_usage_matches_ciphersuite(Key_Constraints usage,
227  const Ciphersuite& suite)
228  {
229  if(usage == NO_CONSTRAINTS)
230  return true; // anything goes ...
231 
232  if(suite.kex_method() == Kex_Algo::STATIC_RSA)
233  {
234  return (usage & KEY_ENCIPHERMENT) | (usage & DATA_ENCIPHERMENT);
235  }
236  else
237  {
238  return (usage & DIGITAL_SIGNATURE) | (usage & NON_REPUDIATION);
239  }
240  }
241 
242 }
243 
244 /*
245 * Process a handshake message
246 */
247 void Client::process_handshake_msg(const Handshake_State* active_state,
248  Handshake_State& state_base,
250  const std::vector<uint8_t>& contents,
251  bool epoch0_restart)
252  {
253  BOTAN_ASSERT_NOMSG(epoch0_restart == false); // only happens on server side
254 
255  Client_Handshake_State& state = dynamic_cast<Client_Handshake_State&>(state_base);
256 
257  if(type == HELLO_REQUEST && active_state)
258  {
259  Hello_Request hello_request(contents);
260 
261  if(state.client_hello())
262  {
263  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Cannot renegotiate during a handshake");
264  }
265 
266  if(policy().allow_server_initiated_renegotiation())
267  {
268  if(secure_renegotiation_supported() || policy().allow_insecure_renegotiation())
269  {
270  state.m_is_reneg = true;
271  this->initiate_handshake(state, true);
272  }
273  else
274  {
275  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client policy prohibits insecure renegotiation");
276  }
277  }
278  else
279  {
280  if(policy().abort_connection_on_undesired_renegotiation())
281  {
282  throw TLS_Exception(Alert::NO_RENEGOTIATION, "Client policy prohibits renegotiation");
283  }
284  else
285  {
286  // RFC 5746 section 4.2
288  }
289  }
290 
291  return;
292  }
293 
294  state.confirm_transition_to(type);
295 
297  state.hash().update(state.handshake_io().format(contents, type));
298 
300  {
301  state.set_expected_next(SERVER_HELLO);
302  state.set_expected_next(HELLO_VERIFY_REQUEST); // might get it again
303 
304  Hello_Verify_Request hello_verify_request(contents);
305  state.hello_verify_request(hello_verify_request);
306  }
307  else if(type == SERVER_HELLO)
308  {
309  state.server_hello(new Server_Hello(contents));
310 
311  if(!state.client_hello()->offered_suite(state.server_hello()->ciphersuite()))
312  {
313  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
314  "Server replied with ciphersuite we didn't send");
315  }
316 
317  if(!Ciphersuite::by_id(state.server_hello()->ciphersuite()).usable_in_version(state.server_hello()->version()))
318  {
319  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
320  "Server replied using a ciphersuite not allowed in version it offered");
321  }
322 
323  if(Ciphersuite::is_scsv(state.server_hello()->ciphersuite()))
324  {
325  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
326  "Server replied with a signaling ciphersuite");
327  }
328 
329  if(state.server_hello()->compression_method() != 0)
330  {
331  throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
332  "Server replied with non-null compression method");
333  }
334 
335  if(state.client_hello()->version() > state.server_hello()->version())
336  {
337  if(state.server_hello()->random_signals_downgrade())
338  throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Downgrade attack detected");
339  }
340 
341  auto client_extn = state.client_hello()->extension_types();
342  auto server_extn = state.server_hello()->extension_types();
343 
344  std::vector<Handshake_Extension_Type> diff;
345 
346  std::set_difference(server_extn.begin(), server_extn.end(),
347  client_extn.begin(), client_extn.end(),
348  std::back_inserter(diff));
349 
350  if(!diff.empty())
351  {
352  // Server sent us back an extension we did not send!
353 
354  std::ostringstream msg;
355  msg << "Server replied with unsupported extensions:";
356  for(auto&& d : diff)
357  msg << " " << static_cast<int>(d);
358  throw TLS_Exception(Alert::UNSUPPORTED_EXTENSION, msg.str());
359  }
360 
361  if(uint16_t srtp = state.server_hello()->srtp_profile())
362  {
363  if(!value_exists(state.client_hello()->srtp_profiles(), srtp))
364  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
365  "Server replied with DTLS-SRTP alg we did not send");
366  }
367 
368  callbacks().tls_examine_extensions(state.server_hello()->extensions(), SERVER);
369 
370  state.set_version(state.server_hello()->version());
371  m_application_protocol = state.server_hello()->next_protocol();
372 
373  secure_renegotiation_check(state.server_hello());
374 
375  const bool server_returned_same_session_id =
376  !state.server_hello()->session_id().empty() &&
377  (state.server_hello()->session_id() == state.client_hello()->session_id());
378 
379  if(server_returned_same_session_id)
380  {
381  // successful resumption
382 
383  /*
384  * In this case, we offered the version used in the original
385  * session, and the server must resume with the same version.
386  */
387  if(state.server_hello()->version() != state.client_hello()->version())
388  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
389  "Server resumed session but with wrong version");
390 
391  if(state.server_hello()->supports_extended_master_secret() &&
392  !state.resumed_session->supports_extended_master_secret())
393  {
394  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
395  "Server resumed session but added extended master secret");
396  }
397 
398  if(!state.server_hello()->supports_extended_master_secret() &&
399  state.resumed_session->supports_extended_master_secret())
400  {
401  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
402  "Server resumed session and removed extended master secret");
403  }
404 
405  state.compute_session_keys(state.resume_master_secret());
406 
407  if(state.server_hello()->supports_session_ticket())
408  {
409  state.set_expected_next(NEW_SESSION_TICKET);
410  }
411  else
412  {
413  state.set_expected_next(HANDSHAKE_CCS);
414  }
415  }
416  else
417  {
418  // new session
419 
420  if(active_state)
421  {
422  // Here we are testing things that should not change during a renegotation,
423  // even if the server creates a new session. Howerver they might change
424  // in a resumption scenario.
425 
426  if(active_state->version() != state.server_hello()->version())
427  throw TLS_Exception(Alert::PROTOCOL_VERSION,
428  "Server changed version after renegotiation");
429 
430  if(state.server_hello()->supports_extended_master_secret() !=
431  active_state->server_hello()->supports_extended_master_secret())
432  {
433  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
434  "Server changed its mind about extended master secret");
435  }
436  }
437 
438  state.resumed_session.reset(); // non-null if we were attempting a resumption
439 
440  if(state.client_hello()->version().is_datagram_protocol() !=
441  state.server_hello()->version().is_datagram_protocol())
442  {
443  throw TLS_Exception(Alert::PROTOCOL_VERSION,
444  "Server replied with different protocol type than we offered");
445  }
446 
447  if(state.version() > state.client_hello()->version())
448  {
449  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
450  "Server replied with later version than client offered");
451  }
452 
453  if(state.version().major_version() == 3 && state.version().minor_version() == 0)
454  {
455  throw TLS_Exception(Alert::PROTOCOL_VERSION,
456  "Server attempting to negotiate SSLv3 which is not supported");
457  }
458 
459  if(!policy().acceptable_protocol_version(state.version()))
460  {
461  throw TLS_Exception(Alert::PROTOCOL_VERSION,
462  "Server version " + state.version().to_string() +
463  " is unacceptable by policy");
464  }
465 
466  if(state.ciphersuite().signature_used() || state.ciphersuite().kex_method() == Kex_Algo::STATIC_RSA)
467  {
468  state.set_expected_next(CERTIFICATE);
469  }
470  else if(state.ciphersuite().kex_method() == Kex_Algo::PSK)
471  {
472  /* PSK is anonymous so no certificate/cert req message is
473  ever sent. The server may or may not send a server kex,
474  depending on if it has an identity hint for us.
475 
476  (EC)DHE_PSK always sends a server key exchange for the
477  DH exchange portion, and is covered by block below
478  */
479 
480  state.set_expected_next(SERVER_KEX);
481  state.set_expected_next(SERVER_HELLO_DONE);
482  }
483  else if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
484  {
485  state.set_expected_next(SERVER_KEX);
486  }
487  else
488  {
489  state.set_expected_next(CERTIFICATE_REQUEST); // optional
490  state.set_expected_next(SERVER_HELLO_DONE);
491  }
492  }
493  }
494  else if(type == CERTIFICATE)
495  {
496  state.server_certs(new Certificate(contents, policy()));
497 
498  const std::vector<X509_Certificate>& server_certs =
499  state.server_certs()->cert_chain();
500 
501  if(server_certs.empty())
502  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
503  "Client: No certificates sent by server");
504 
505  /*
506  If the server supports certificate status messages,
507  certificate verification happens after we receive the server hello done,
508  in case an OCSP response was also available
509  */
510 
511  X509_Certificate server_cert = server_certs[0];
512 
513  if(active_state && active_state->server_certs())
514  {
515  X509_Certificate current_cert = active_state->server_certs()->cert_chain().at(0);
516 
517  if(current_cert != server_cert)
518  throw TLS_Exception(Alert::BAD_CERTIFICATE, "Server certificate changed during renegotiation");
519  }
520 
521  std::unique_ptr<Public_Key> peer_key(server_cert.subject_public_key());
522 
523  const std::string expected_key_type =
524  state.ciphersuite().signature_used() ? state.ciphersuite().sig_algo() : "RSA";
525 
526  if(peer_key->algo_name() != expected_key_type)
527  throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
528  "Certificate key type did not match ciphersuite");
529 
530  if(!key_usage_matches_ciphersuite(server_cert.constraints(), state.ciphersuite()))
531  throw TLS_Exception(Alert::BAD_CERTIFICATE,
532  "Certificate usage constraints do not allow this ciphersuite");
533 
534  state.server_public_key.reset(peer_key.release());
535 
536  if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
537  {
538  state.set_expected_next(SERVER_KEX);
539  }
540  else
541  {
542  state.set_expected_next(CERTIFICATE_REQUEST); // optional
543  state.set_expected_next(SERVER_HELLO_DONE);
544  }
545 
546  if(state.server_hello()->supports_certificate_status_message())
547  {
548  state.set_expected_next(CERTIFICATE_STATUS); // optional
549  }
550  else
551  {
552  try
553  {
554  auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-client", m_info.hostname());
555 
556  callbacks().tls_verify_cert_chain(server_certs,
557  {},
558  trusted_CAs,
560  m_info.hostname(),
561  policy());
562  }
563  catch(TLS_Exception&)
564  {
565  throw;
566  }
567  catch(std::exception& e)
568  {
569  throw TLS_Exception(Alert::INTERNAL_ERROR, e.what());
570  }
571  }
572  }
573  else if(type == CERTIFICATE_STATUS)
574  {
575  state.server_cert_status(new Certificate_Status(contents));
576 
577  if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
578  {
579  state.set_expected_next(SERVER_KEX);
580  }
581  else
582  {
583  state.set_expected_next(CERTIFICATE_REQUEST); // optional
584  state.set_expected_next(SERVER_HELLO_DONE);
585  }
586  }
587  else if(type == SERVER_KEX)
588  {
589  if(state.ciphersuite().psk_ciphersuite() == false)
590  state.set_expected_next(CERTIFICATE_REQUEST); // optional
591  state.set_expected_next(SERVER_HELLO_DONE);
592 
593  state.server_kex(
594  new Server_Key_Exchange(contents,
595  state.ciphersuite().kex_method(),
596  state.ciphersuite().auth_method(),
597  state.version())
598  );
599 
600  if(state.ciphersuite().signature_used())
601  {
602  const Public_Key& server_key = state.get_server_public_key();
603 
604  if(!state.server_kex()->verify(server_key, state, policy()))
605  {
606  throw TLS_Exception(Alert::DECRYPT_ERROR,
607  "Bad signature on server key exchange");
608  }
609  }
610  }
611  else if(type == CERTIFICATE_REQUEST)
612  {
613  state.set_expected_next(SERVER_HELLO_DONE);
614  state.cert_req(new Certificate_Req(contents, state.version()));
615  }
616  else if(type == SERVER_HELLO_DONE)
617  {
618  state.server_hello_done(new Server_Hello_Done(contents));
619 
620  if(state.server_certs() != nullptr &&
621  state.server_hello()->supports_certificate_status_message())
622  {
623  try
624  {
625  auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-client", m_info.hostname());
626 
627  std::vector<std::shared_ptr<const OCSP::Response>> ocsp;
628  if(state.server_cert_status() != nullptr)
629  {
630  try {
631  ocsp.push_back(std::make_shared<OCSP::Response>(state.server_cert_status()->response()));
632  }
633  catch(Decoding_Error&)
634  {
635  // ignore it here because it might be our fault
636  }
637  }
638 
639  callbacks().tls_verify_cert_chain(state.server_certs()->cert_chain(),
640  ocsp,
641  trusted_CAs,
643  m_info.hostname(),
644  policy());
645  }
646  catch(TLS_Exception&)
647  {
648  throw;
649  }
650  catch(std::exception& e)
651  {
652  throw TLS_Exception(Alert::INTERNAL_ERROR, e.what());
653  }
654  }
655 
656  if(state.received_handshake_msg(CERTIFICATE_REQUEST))
657  {
658  const auto& types = state.cert_req()->acceptable_cert_types();
659 
660  std::vector<X509_Certificate> client_certs =
661  m_creds.find_cert_chain(types,
662  state.cert_req()->acceptable_CAs(),
663  "tls-client",
664  m_info.hostname());
665 
666  state.client_certs(new Certificate(state.handshake_io(),
667  state.hash(),
668  client_certs));
669  }
670 
671  state.client_kex(
672  new Client_Key_Exchange(state.handshake_io(),
673  state,
674  policy(),
675  m_creds,
676  state.server_public_key.get(),
677  m_info.hostname(),
678  rng())
679  );
680 
681  state.compute_session_keys();
682 
683  if(state.received_handshake_msg(CERTIFICATE_REQUEST) &&
684  !state.client_certs()->empty())
685  {
686  Private_Key* private_key =
687  m_creds.private_key_for(state.client_certs()->cert_chain()[0],
688  "tls-client",
689  m_info.hostname());
690 
691  state.client_verify(
692  new Certificate_Verify(state.handshake_io(),
693  state,
694  policy(),
695  rng(),
696  private_key)
697  );
698  }
699 
700  state.handshake_io().send(Change_Cipher_Spec());
701 
703 
704  state.client_finished(new Finished(state.handshake_io(), state, CLIENT));
705 
706  if(state.server_hello()->supports_session_ticket())
707  state.set_expected_next(NEW_SESSION_TICKET);
708  else
709  state.set_expected_next(HANDSHAKE_CCS);
710  }
711  else if(type == NEW_SESSION_TICKET)
712  {
713  state.new_session_ticket(new New_Session_Ticket(contents));
714 
715  state.set_expected_next(HANDSHAKE_CCS);
716  }
717  else if(type == HANDSHAKE_CCS)
718  {
719  state.set_expected_next(FINISHED);
720 
722  }
723  else if(type == FINISHED)
724  {
725  state.server_finished(new Finished(contents));
726 
727  if(!state.server_finished()->verify(state, SERVER))
728  throw TLS_Exception(Alert::DECRYPT_ERROR,
729  "Finished message didn't verify");
730 
731  state.hash().update(state.handshake_io().format(contents, type));
732 
733  if(!state.client_finished()) // session resume case
734  {
735  state.handshake_io().send(Change_Cipher_Spec());
737  state.client_finished(new Finished(state.handshake_io(), state, CLIENT));
738  }
739 
740  std::vector<uint8_t> session_id = state.server_hello()->session_id();
741 
742  const std::vector<uint8_t>& session_ticket = state.session_ticket();
743 
744  if(session_id.empty() && !session_ticket.empty())
745  session_id = make_hello_random(rng(), policy());
746 
747  Session session_info(
748  session_id,
749  state.session_keys().master_secret(),
750  state.server_hello()->version(),
751  state.server_hello()->ciphersuite(),
752  CLIENT,
753  state.server_hello()->supports_extended_master_secret(),
754  state.server_hello()->supports_encrypt_then_mac(),
755  get_peer_cert_chain(state),
756  session_ticket,
757  m_info,
758  "",
759  state.server_hello()->srtp_profile()
760  );
761 
762  const bool should_save = save_session(session_info);
763 
764  if(session_id.size() > 0 && state.is_a_resumption() == false)
765  {
766  if(should_save)
767  session_manager().save(session_info);
768  else
769  session_manager().remove_entry(session_info.session_id());
770  }
771 
773  }
774  else
775  throw Unexpected_Message("Unknown handshake message received");
776  }
777 
778 }
779 
780 }
virtual std::vector< X509_Certificate > find_cert_chain(const std::vector< std::string > &cert_key_types, const std::vector< X509_DN > &acceptable_CAs, const std::string &type, const std::string &context)
virtual void remove_entry(const std::vector< uint8_t > &session_id)=0
virtual std::string srp_identifier(const std::string &type, const std::string &context)
std::function< void(Alert, const uint8_t[], size_t)> alert_cb
Definition: tls_channel.h:42
void change_cipher_spec_reader(Connection_Side side)
std::unique_ptr< Session > resumed_session
Definition: tls_client.cpp:55
int(* final)(unsigned char *, CTX *)
static bool is_scsv(uint16_t suite)
void change_cipher_spec_writer(Connection_Side side)
Client(Callbacks &callbacks, Session_Manager &session_manager, Credentials_Manager &creds, const Policy &policy, RandomNumberGenerator &rng, const Server_Information &server_info=Server_Information(), const Protocol_Version &offer_version=Protocol_Version::latest_tls_version(), const std::vector< std::string > &next_protocols={}, size_t reserved_io_buffer_size=TLS::Client::IO_BUF_DEFAULT_SIZE)
Definition: tls_client.cpp:64
void send_warning_alert(Alert::Type type)
Definition: tls_channel.h:139
std::function< void(const uint8_t[], size_t)> output_fn
Definition: tls_channel.h:40
bool secure_renegotiation_supported() const
#define BOTAN_STATE_CHECK(expr)
Definition: assert.h:49
Handshake_State & create_handshake_state(Protocol_Version version)
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:68
RandomNumberGenerator & rng()
Definition: tls_channel.h:234
std::string hostname() const
MechanismType type
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const
std::function< bool(const Session &)> handshake_cb
Definition: tls_channel.h:43
bool save_session(const Session &session)
virtual bool only_resume_with_exact_version() const
Definition: tls_policy.cpp:346
virtual void tls_verify_cert_chain(const std::vector< X509_Certificate > &cert_chain, const std::vector< std::shared_ptr< const OCSP::Response >> &ocsp_responses, const std::vector< Certificate_Store *> &trusted_roots, Usage_Type usage, const std::string &hostname, const TLS::Policy &policy)
Definition: alg_id.cpp:13
virtual void tls_examine_extensions(const Extensions &extn, Connection_Side which_side)
void secure_renegotiation_check(const Client_Hello *client_hello)
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, const Policy &policy)
std::function< void(const uint8_t[], size_t)> data_cb
Definition: tls_channel.h:41
std::unique_ptr< Public_Key > server_public_key
Definition: tls_client.cpp:53
bool value_exists(const std::vector< T > &vec, const T &val)
Definition: stl_util.h:86
static Ciphersuite by_id(uint16_t suite)
virtual std::vector< Certificate_Store * > trusted_certificate_authorities(const std::string &type, const std::string &context)
Callbacks & callbacks() const
Definition: tls_channel.h:242
const Policy & policy() const
Definition: tls_channel.h:238
virtual bool acceptable_protocol_version(Protocol_Version version) const
Definition: tls_policy.cpp:278
virtual void save(const Session &session)=0
bool m_is_reneg
Definition: tls_client.cpp:56
Session_Manager & session_manager()
Definition: tls_channel.h:236
std::function< void(const Handshake_Message &)> handshake_msg_cb
Definition: tls_channel.h:44