Botan  2.11.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 */
64 Client::Client(Callbacks& callbacks,
65  Session_Manager& session_manager,
66  Credentials_Manager& creds,
67  const Policy& policy,
68  RandomNumberGenerator& rng,
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, offer_version.is_datagram_protocol(),
74  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,
88  RandomNumberGenerator& rng,
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, 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,
109  RandomNumberGenerator& rng,
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, 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(),
197  secure_renegotiation_data_for_client_hello(),
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(),
216  secure_renegotiation_data_for_client_hello(),
217  client_settings,
218  next_protocols));
219  }
220 
221  secure_renegotiation_check(state.client_hello());
222  }
223 
224 /*
225 * Process a handshake message
226 */
227 void Client::process_handshake_msg(const Handshake_State* active_state,
228  Handshake_State& state_base,
230  const std::vector<uint8_t>& contents)
231  {
232  Client_Handshake_State& state = dynamic_cast<Client_Handshake_State&>(state_base);
233 
234  if(type == HELLO_REQUEST && active_state)
235  {
236  Hello_Request hello_request(contents);
237 
238  if(state.client_hello())
239  {
240  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Cannot renegotiate during a handshake");
241  }
242 
243  if(policy().allow_server_initiated_renegotiation())
244  {
245  if(secure_renegotiation_supported() || policy().allow_insecure_renegotiation())
246  {
247  state.m_is_reneg = true;
248  this->initiate_handshake(state, true);
249  }
250  else
251  {
252  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client policy prohibits insecure renegotiation");
253  }
254  }
255  else
256  {
257  if(policy().abort_connection_on_undesired_renegotiation())
258  {
259  throw TLS_Exception(Alert::NO_RENEGOTIATION, "Client policy prohibits renegotiation");
260  }
261  else
262  {
263  // RFC 5746 section 4.2
264  send_warning_alert(Alert::NO_RENEGOTIATION);
265  }
266  }
267 
268  return;
269  }
270 
271  state.confirm_transition_to(type);
272 
274  state.hash().update(state.handshake_io().format(contents, type));
275 
277  {
278  state.set_expected_next(SERVER_HELLO);
279  state.set_expected_next(HELLO_VERIFY_REQUEST); // might get it again
280 
281  Hello_Verify_Request hello_verify_request(contents);
282  state.hello_verify_request(hello_verify_request);
283  }
284  else if(type == SERVER_HELLO)
285  {
286  state.server_hello(new Server_Hello(contents));
287 
288  if(!state.client_hello()->offered_suite(state.server_hello()->ciphersuite()))
289  {
290  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
291  "Server replied with ciphersuite we didn't send");
292  }
293 
294  if(!Ciphersuite::by_id(state.server_hello()->ciphersuite()).usable_in_version(state.server_hello()->version()))
295  {
296  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
297  "Server replied using a ciphersuite not allowed in version it offered");
298  }
299 
300  if(Ciphersuite::is_scsv(state.server_hello()->ciphersuite()))
301  {
302  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
303  "Server replied with a signaling ciphersuite");
304  }
305 
306  if(state.server_hello()->compression_method() != 0)
307  {
308  throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
309  "Server replied with non-null compression method");
310  }
311 
312  auto client_extn = state.client_hello()->extension_types();
313  auto server_extn = state.server_hello()->extension_types();
314 
315  std::vector<Handshake_Extension_Type> diff;
316 
317  std::set_difference(server_extn.begin(), server_extn.end(),
318  client_extn.begin(), client_extn.end(),
319  std::back_inserter(diff));
320 
321  if(!diff.empty())
322  {
323  // Server sent us back an extension we did not send!
324 
325  std::ostringstream msg;
326  msg << "Server replied with unsupported extensions:";
327  for(auto&& d : diff)
328  msg << " " << static_cast<int>(d);
329  throw TLS_Exception(Alert::UNSUPPORTED_EXTENSION, msg.str());
330  }
331 
332  if(uint16_t srtp = state.server_hello()->srtp_profile())
333  {
334  if(!value_exists(state.client_hello()->srtp_profiles(), srtp))
335  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
336  "Server replied with DTLS-SRTP alg we did not send");
337  }
338 
339  callbacks().tls_examine_extensions(state.server_hello()->extensions(), SERVER);
340 
341  state.set_version(state.server_hello()->version());
342  m_application_protocol = state.server_hello()->next_protocol();
343 
344  secure_renegotiation_check(state.server_hello());
345 
346  const bool server_returned_same_session_id =
347  !state.server_hello()->session_id().empty() &&
348  (state.server_hello()->session_id() == state.client_hello()->session_id());
349 
350  if(server_returned_same_session_id)
351  {
352  // successful resumption
353 
354  /*
355  * In this case, we offered the version used in the original
356  * session, and the server must resume with the same version.
357  */
358  if(state.server_hello()->version() != state.client_hello()->version())
359  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
360  "Server resumed session but with wrong version");
361 
362  if(state.server_hello()->supports_extended_master_secret() &&
363  !state.resumed_session->supports_extended_master_secret())
364  {
365  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
366  "Server resumed session but added extended master secret");
367  }
368 
369  if(!state.server_hello()->supports_extended_master_secret() &&
370  state.resumed_session->supports_extended_master_secret())
371  {
372  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
373  "Server resumed session and removed extended master secret");
374  }
375 
376  state.compute_session_keys(state.resume_master_secret());
377 
378  if(state.server_hello()->supports_session_ticket())
379  {
380  state.set_expected_next(NEW_SESSION_TICKET);
381  }
382  else
383  {
384  state.set_expected_next(HANDSHAKE_CCS);
385  }
386  }
387  else
388  {
389  // new session
390 
391  if(active_state)
392  {
393  // Here we are testing things that should not change during a renegotation,
394  // even if the server creates a new session. Howerver they might change
395  // in a resumption scenario.
396 
397  if(active_state->version() != state.server_hello()->version())
398  throw TLS_Exception(Alert::PROTOCOL_VERSION,
399  "Server changed version after renegotiation");
400 
401  if(state.server_hello()->supports_extended_master_secret() !=
402  active_state->server_hello()->supports_extended_master_secret())
403  {
404  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
405  "Server changed its mind about extended master secret");
406  }
407  }
408 
409  state.resumed_session.reset(); // non-null if we were attempting a resumption
410 
411  if(state.client_hello()->version().is_datagram_protocol() !=
412  state.server_hello()->version().is_datagram_protocol())
413  {
414  throw TLS_Exception(Alert::PROTOCOL_VERSION,
415  "Server replied with different protocol type than we offered");
416  }
417 
418  if(state.version() > state.client_hello()->version())
419  {
420  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
421  "Server replied with later version than client offered");
422  }
423 
424  if(state.version().major_version() == 3 && state.version().minor_version() == 0)
425  {
426  throw TLS_Exception(Alert::PROTOCOL_VERSION,
427  "Server attempting to negotiate SSLv3 which is not supported");
428  }
429 
430  if(!policy().acceptable_protocol_version(state.version()))
431  {
432  throw TLS_Exception(Alert::PROTOCOL_VERSION,
433  "Server version " + state.version().to_string() +
434  " is unacceptable by policy");
435  }
436 
437  if(state.ciphersuite().signature_used() || state.ciphersuite().kex_method() == Kex_Algo::STATIC_RSA)
438  {
439  state.set_expected_next(CERTIFICATE);
440  }
441  else if(state.ciphersuite().kex_method() == Kex_Algo::PSK)
442  {
443  /* PSK is anonymous so no certificate/cert req message is
444  ever sent. The server may or may not send a server kex,
445  depending on if it has an identity hint for us.
446 
447  (EC)DHE_PSK always sends a server key exchange for the
448  DH exchange portion, and is covered by block below
449  */
450 
451  state.set_expected_next(SERVER_KEX);
452  state.set_expected_next(SERVER_HELLO_DONE);
453  }
454  else if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
455  {
456  state.set_expected_next(SERVER_KEX);
457  }
458  else
459  {
460  state.set_expected_next(CERTIFICATE_REQUEST); // optional
461  state.set_expected_next(SERVER_HELLO_DONE);
462  }
463  }
464  }
465  else if(type == CERTIFICATE)
466  {
467  state.server_certs(new Certificate(contents, policy()));
468 
469  const std::vector<X509_Certificate>& server_certs =
470  state.server_certs()->cert_chain();
471 
472  if(server_certs.empty())
473  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
474  "Client: No certificates sent by server");
475 
476  /*
477  If the server supports certificate status messages,
478  certificate verification happens after we receive the server hello done,
479  in case an OCSP response was also available
480  */
481 
482  X509_Certificate server_cert = server_certs[0];
483 
484  if(active_state && active_state->server_certs())
485  {
486  X509_Certificate current_cert = active_state->server_certs()->cert_chain().at(0);
487 
488  if(current_cert != server_cert)
489  throw TLS_Exception(Alert::BAD_CERTIFICATE, "Server certificate changed during renegotiation");
490  }
491 
492  std::unique_ptr<Public_Key> peer_key(server_cert.subject_public_key());
493 
494  const std::string expected_key_type =
495  state.ciphersuite().signature_used() ? state.ciphersuite().sig_algo() : "RSA";
496 
497  if(peer_key->algo_name() != expected_key_type)
498  throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
499  "Certificate key type did not match ciphersuite");
500 
501  state.server_public_key.reset(peer_key.release());
502 
503  if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
504  {
505  state.set_expected_next(SERVER_KEX);
506  }
507  else
508  {
509  state.set_expected_next(CERTIFICATE_REQUEST); // optional
510  state.set_expected_next(SERVER_HELLO_DONE);
511  }
512 
513  if(state.server_hello()->supports_certificate_status_message())
514  {
515  state.set_expected_next(CERTIFICATE_STATUS); // optional
516  }
517  else
518  {
519  try
520  {
521  auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-client", m_info.hostname());
522 
523  callbacks().tls_verify_cert_chain(server_certs,
524  {},
525  trusted_CAs,
526  Usage_Type::TLS_SERVER_AUTH,
527  m_info.hostname(),
528  policy());
529  }
530  catch(TLS_Exception&)
531  {
532  throw;
533  }
534  catch(std::exception& e)
535  {
536  throw TLS_Exception(Alert::INTERNAL_ERROR, e.what());
537  }
538  }
539  }
540  else if(type == CERTIFICATE_STATUS)
541  {
542  state.server_cert_status(new Certificate_Status(contents));
543 
544  if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
545  {
546  state.set_expected_next(SERVER_KEX);
547  }
548  else
549  {
550  state.set_expected_next(CERTIFICATE_REQUEST); // optional
551  state.set_expected_next(SERVER_HELLO_DONE);
552  }
553  }
554  else if(type == SERVER_KEX)
555  {
556  if(state.ciphersuite().psk_ciphersuite() == false)
557  state.set_expected_next(CERTIFICATE_REQUEST); // optional
558  state.set_expected_next(SERVER_HELLO_DONE);
559 
560  state.server_kex(
561  new Server_Key_Exchange(contents,
562  state.ciphersuite().kex_method(),
563  state.ciphersuite().auth_method(),
564  state.version())
565  );
566 
567  if(state.ciphersuite().signature_used())
568  {
569  const Public_Key& server_key = state.get_server_public_key();
570 
571  if(!state.server_kex()->verify(server_key, state, policy()))
572  {
573  throw TLS_Exception(Alert::DECRYPT_ERROR,
574  "Bad signature on server key exchange");
575  }
576  }
577  }
578  else if(type == CERTIFICATE_REQUEST)
579  {
580  state.set_expected_next(SERVER_HELLO_DONE);
581  state.cert_req(new Certificate_Req(contents, state.version()));
582  }
583  else if(type == SERVER_HELLO_DONE)
584  {
585  state.server_hello_done(new Server_Hello_Done(contents));
586 
587  if(state.server_certs() != nullptr &&
588  state.server_hello()->supports_certificate_status_message())
589  {
590  try
591  {
592  auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-client", m_info.hostname());
593 
594  std::vector<std::shared_ptr<const OCSP::Response>> ocsp;
595  if(state.server_cert_status() != nullptr)
596  {
597  try {
598  ocsp.push_back(std::make_shared<OCSP::Response>(state.server_cert_status()->response()));
599  }
600  catch(Decoding_Error&)
601  {
602  // ignore it here because it might be our fault
603  }
604  }
605 
606  callbacks().tls_verify_cert_chain(state.server_certs()->cert_chain(),
607  ocsp,
608  trusted_CAs,
609  Usage_Type::TLS_SERVER_AUTH,
610  m_info.hostname(),
611  policy());
612  }
613  catch(TLS_Exception&)
614  {
615  throw;
616  }
617  catch(std::exception& e)
618  {
619  throw TLS_Exception(Alert::INTERNAL_ERROR, e.what());
620  }
621  }
622 
623  if(state.received_handshake_msg(CERTIFICATE_REQUEST))
624  {
625  const auto& types = state.cert_req()->acceptable_cert_types();
626 
627  std::vector<X509_Certificate> client_certs =
628  m_creds.find_cert_chain(types,
629  state.cert_req()->acceptable_CAs(),
630  "tls-client",
631  m_info.hostname());
632 
633  state.client_certs(new Certificate(state.handshake_io(),
634  state.hash(),
635  client_certs));
636  }
637 
638  state.client_kex(
639  new Client_Key_Exchange(state.handshake_io(),
640  state,
641  policy(),
642  m_creds,
643  state.server_public_key.get(),
644  m_info.hostname(),
645  rng())
646  );
647 
648  state.compute_session_keys();
649 
650  if(state.received_handshake_msg(CERTIFICATE_REQUEST) &&
651  !state.client_certs()->empty())
652  {
653  Private_Key* private_key =
654  m_creds.private_key_for(state.client_certs()->cert_chain()[0],
655  "tls-client",
656  m_info.hostname());
657 
658  state.client_verify(
659  new Certificate_Verify(state.handshake_io(),
660  state,
661  policy(),
662  rng(),
663  private_key)
664  );
665  }
666 
667  state.handshake_io().send(Change_Cipher_Spec());
668 
669  change_cipher_spec_writer(CLIENT);
670 
671  state.client_finished(new Finished(state.handshake_io(), state, CLIENT));
672 
673  if(state.server_hello()->supports_session_ticket())
674  state.set_expected_next(NEW_SESSION_TICKET);
675  else
676  state.set_expected_next(HANDSHAKE_CCS);
677  }
678  else if(type == NEW_SESSION_TICKET)
679  {
680  state.new_session_ticket(new New_Session_Ticket(contents));
681 
682  state.set_expected_next(HANDSHAKE_CCS);
683  }
684  else if(type == HANDSHAKE_CCS)
685  {
686  state.set_expected_next(FINISHED);
687 
688  change_cipher_spec_reader(CLIENT);
689  }
690  else if(type == FINISHED)
691  {
692  state.server_finished(new Finished(contents));
693 
694  if(!state.server_finished()->verify(state, SERVER))
695  throw TLS_Exception(Alert::DECRYPT_ERROR,
696  "Finished message didn't verify");
697 
698  state.hash().update(state.handshake_io().format(contents, type));
699 
700  if(!state.client_finished()) // session resume case
701  {
702  state.handshake_io().send(Change_Cipher_Spec());
703  change_cipher_spec_writer(CLIENT);
704  state.client_finished(new Finished(state.handshake_io(), state, CLIENT));
705  }
706 
707  std::vector<uint8_t> session_id = state.server_hello()->session_id();
708 
709  const std::vector<uint8_t>& session_ticket = state.session_ticket();
710 
711  if(session_id.empty() && !session_ticket.empty())
712  session_id = make_hello_random(rng(), policy());
713 
714  Session session_info(
715  session_id,
716  state.session_keys().master_secret(),
717  state.server_hello()->version(),
718  state.server_hello()->ciphersuite(),
719  CLIENT,
720  state.server_hello()->supports_extended_master_secret(),
721  state.server_hello()->supports_encrypt_then_mac(),
722  get_peer_cert_chain(state),
723  session_ticket,
724  m_info,
725  "",
726  state.server_hello()->srtp_profile()
727  );
728 
729  const bool should_save = save_session(session_info);
730 
731  if(session_id.size() > 0 && state.is_a_resumption() == false)
732  {
733  if(should_save)
734  session_manager().save(session_info);
735  else
736  session_manager().remove_entry(session_info.session_id());
737  }
738 
739  activate_session();
740  }
741  else
742  throw Unexpected_Message("Unknown handshake message received");
743  }
744 
745 }
746 
747 }
bool RandomNumberGenerator & rng
Definition: numthry.h:176
botan_rng_t rng
Definition: ffi.h:864
const Private_Key & private_key
Definition: keypair.h:28
std::unique_ptr< Session > resumed_session
Definition: tls_client.cpp:55
int(* final)(unsigned char *, CTX *)
#define BOTAN_STATE_CHECK(expr)
Definition: assert.h:49
MechanismType type
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
BigInt const BigInt & d
Definition: bigint.h:1093
Definition: alg_id.cpp:13
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, const Policy &policy)
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
int(* init)(CTX *)
botan_mp_t botan_mp_t botan_mp_t e
Definition: ffi.h:1116
bool m_is_reneg
Definition: tls_client.cpp:56