Botan  2.18.1
Crypto and TLS for C++11
Classes | Public Member Functions | List of all members
Botan::TLS::Client_Hello Class Referencefinal

#include <tls_messages.h>

Inheritance diagram for Botan::TLS::Client_Hello:
Botan::TLS::Handshake_Message

Classes

class  Settings
 

Public Member Functions

const std::vector< uint16_t > & ciphersuites () const
 
 Client_Hello (Handshake_IO &io, Handshake_Hash &hash, const Policy &policy, Callbacks &cb, RandomNumberGenerator &rng, const std::vector< uint8_t > &reneg_info, const Client_Hello::Settings &client_settings, const std::vector< std::string > &next_protocols)
 
 Client_Hello (Handshake_IO &io, Handshake_Hash &hash, const Policy &policy, Callbacks &cb, RandomNumberGenerator &rng, const std::vector< uint8_t > &reneg_info, const Session &resumed_session, const std::vector< std::string > &next_protocols)
 
 Client_Hello (const std::vector< uint8_t > &buf)
 
const std::vector< uint8_t > & compression_methods () const
 
const std::vector< uint8_t > & cookie () const
 
std::vector< uint8_t > cookie_input_data () const
 
std::set< Handshake_Extension_Typeextension_types () const
 
const Extensionsextensions () const
 
std::vector< std::string > next_protocols () const
 
bool offered_suite (uint16_t ciphersuite) const
 
bool prefers_compressed_ec_points () const
 
const std::vector< uint8_t > & random () const
 
std::vector< uint8_t > renegotiation_info () const
 
bool secure_renegotiation () const
 
bool sent_fallback_scsv () const
 
bool sent_signature_algorithms () const
 
const std::vector< uint8_t > & session_id () const
 
std::vector< uint8_t > session_ticket () const
 
std::vector< Signature_Schemesignature_schemes () const
 
std::string sni_hostname () const
 
std::vector< uint16_t > srtp_profiles () const
 
std::vector< Group_Paramssupported_dh_groups () const
 
std::vector< Group_Paramssupported_ecc_curves () const
 
std::vector< Protocol_Versionsupported_versions () const
 
bool supports_alpn () const
 
bool supports_cert_status_message () const
 
bool supports_encrypt_then_mac () const
 
bool supports_extended_master_secret () const
 
bool supports_session_ticket () const
 
Handshake_Type type () const override
 
std::string type_string () const
 
void update_hello_cookie (const Hello_Verify_Request &hello_verify)
 
Protocol_Version version () const
 

Detailed Description

Client Hello Message

Definition at line 70 of file tls_messages.h.

Constructor & Destructor Documentation

◆ Client_Hello() [1/3]

Botan::TLS::Client_Hello::Client_Hello ( Handshake_IO io,
Handshake_Hash hash,
const Policy policy,
Callbacks cb,
RandomNumberGenerator rng,
const std::vector< uint8_t > &  reneg_info,
const Client_Hello::Settings client_settings,
const std::vector< std::string > &  next_protocols 
)

Definition at line 82 of file msg_client_hello.cpp.

References Botan::TLS::Policy::acceptable_protocol_version(), Botan::TLS::Extensions::add(), Botan::TLS::Policy::allowed_signature_schemes(), Botan::TLS::CLIENT, hash, Botan::TLS::Client_Hello::Settings::hostname(), Botan::TLS::Protocol_Version::is_datagram_protocol(), Botan::TLS::Policy::key_exchange_groups(), Botan::TLS::Policy::negotiate_encrypt_then_mac(), next_protocols(), Botan::TLS::Client_Hello::Settings::protocol_version(), Botan::TLS::Handshake_IO::send(), Botan::TLS::Policy::send_fallback_scsv(), Botan::TLS::Client_Hello::Settings::srp_identifier(), Botan::TLS::Policy::srtp_profiles(), Botan::TLS::Policy::support_cert_status_message(), Botan::TLS::Protocol_Version::supports_negotiable_signature_algorithms(), Botan::TLS::TLS_FALLBACK_SCSV, Botan::TLS::Callbacks::tls_modify_extensions(), Botan::TLS::Protocol_Version::to_string(), and Botan::TLS::Policy::use_ecc_point_compression().

89  :
90  m_version(client_settings.protocol_version()),
91  m_random(make_hello_random(rng, policy)),
92  m_suites(policy.ciphersuite_list(m_version, !client_settings.srp_identifier().empty())),
93  m_comp_methods(1)
94  {
95  if(!policy.acceptable_protocol_version(m_version))
96  throw Internal_Error("Offering " + m_version.to_string() +
97  " but our own policy does not accept it");
98 
99  /*
100  * Place all empty extensions in front to avoid a bug in some systems
101  * which reject hellos when the last extension in the list is empty.
102  */
103  m_extensions.add(new Extended_Master_Secret);
104  m_extensions.add(new Session_Ticket());
105 
106  if(policy.negotiate_encrypt_then_mac())
107  m_extensions.add(new Encrypt_then_MAC);
108 
109  m_extensions.add(new Renegotiation_Extension(reneg_info));
110 
111  m_extensions.add(new Supported_Versions(m_version, policy));
112 
113  if(client_settings.hostname() != "")
114  m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
115 
116  if(policy.support_cert_status_message())
117  m_extensions.add(new Certificate_Status_Request({}, {}));
118 
119  if(reneg_info.empty() && !next_protocols.empty())
120  m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
121 
123  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
124 
125  if(m_version.is_datagram_protocol())
126  m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
127 
128 #if defined(BOTAN_HAS_SRP6)
129  m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
130 #else
131  if(!client_settings.srp_identifier().empty())
132  {
133  throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
134  }
135 #endif
136 
137  std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
138 
139  if(supported_groups->ec_groups().size() > 0)
140  {
141  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
142  }
143 
144  m_extensions.add(supported_groups.release());
145 
146  cb.tls_modify_extensions(m_extensions, CLIENT);
147 
148  if(policy.send_fallback_scsv(client_settings.protocol_version()))
149  m_suites.push_back(TLS_FALLBACK_SCSV);
150 
151  hash.update(io.send(*this));
152  }
void add(Extension *extn)
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
std::string to_string() const
Definition: tls_version.cpp:15
std::vector< std::string > next_protocols() const
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, const Policy &policy)
MechanismType hash

◆ Client_Hello() [2/3]

Botan::TLS::Client_Hello::Client_Hello ( Handshake_IO io,
Handshake_Hash hash,
const Policy policy,
Callbacks cb,
RandomNumberGenerator rng,
const std::vector< uint8_t > &  reneg_info,
const Session resumed_session,
const std::vector< std::string > &  next_protocols 
)

Definition at line 157 of file msg_client_hello.cpp.

References Botan::TLS::Policy::acceptable_protocol_version(), Botan::TLS::Extensions::add(), Botan::TLS::Policy::allowed_signature_schemes(), Botan::TLS::Session::ciphersuite_code(), Botan::TLS::CLIENT, hash, Botan::TLS::Server_Information::hostname(), Botan::TLS::Policy::key_exchange_groups(), next_protocols(), Botan::TLS::Handshake_IO::send(), Botan::TLS::Session::server_info(), Botan::TLS::Session::session_ticket(), Botan::TLS::Session::srp_identifier(), Botan::TLS::Policy::support_cert_status_message(), Botan::TLS::Session::supports_encrypt_then_mac(), Botan::TLS::Protocol_Version::supports_negotiable_signature_algorithms(), Botan::TLS::Callbacks::tls_modify_extensions(), Botan::TLS::Protocol_Version::to_string(), Botan::TLS::Policy::use_ecc_point_compression(), and Botan::value_exists().

164  :
165  m_version(session.version()),
166  m_session_id(session.session_id()),
167  m_random(make_hello_random(rng, policy)),
168  m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))),
169  m_comp_methods(1)
170  {
171  if(!policy.acceptable_protocol_version(m_version))
172  throw Internal_Error("Offering " + m_version.to_string() +
173  " but our own policy does not accept it");
174 
175  if(!value_exists(m_suites, session.ciphersuite_code()))
176  m_suites.push_back(session.ciphersuite_code());
177 
178  /*
179  We always add the EMS extension, even if not used in the original session.
180  If the server understands it and follows the RFC it should reject our resume
181  attempt and upgrade us to a new session with the EMS protection.
182  */
183  m_extensions.add(new Extended_Master_Secret);
184 
185  m_extensions.add(new Renegotiation_Extension(reneg_info));
186  m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
187  m_extensions.add(new Session_Ticket(session.session_ticket()));
188 
189  if(policy.support_cert_status_message())
190  m_extensions.add(new Certificate_Status_Request({}, {}));
191 
192  std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
193 
194  if(supported_groups->ec_groups().size() > 0)
195  {
196  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
197  }
198 
199  m_extensions.add(supported_groups.release());
200 
201  if(session.supports_encrypt_then_mac())
202  m_extensions.add(new Encrypt_then_MAC);
203 
204 #if defined(BOTAN_HAS_SRP6)
205  m_extensions.add(new SRP_Identifier(session.srp_identifier()));
206 #else
207  if(!session.srp_identifier().empty())
208  {
209  throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled");
210  }
211 #endif
212 
214  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
215 
216  if(reneg_info.empty() && !next_protocols.empty())
217  m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
218 
219  cb.tls_modify_extensions(m_extensions, CLIENT);
220 
221  hash.update(io.send(*this));
222  }
void add(Extension *extn)
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
std::string to_string() const
Definition: tls_version.cpp:15
std::vector< std::string > next_protocols() const
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, const Policy &policy)
bool value_exists(const std::vector< T > &vec, const T &val)
Definition: stl_util.h:86
MechanismType hash

◆ Client_Hello() [3/3]

Botan::TLS::Client_Hello::Client_Hello ( const std::vector< uint8_t > &  buf)
explicit

Definition at line 284 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::add(), Botan::TLS::CLIENT, Botan::TLS::Extensions::deserialize(), Botan::TLS::Extensions::get(), Botan::TLS::TLS_Data_Reader::get_byte(), Botan::TLS::TLS_Data_Reader::get_fixed(), Botan::TLS::TLS_Data_Reader::get_range(), Botan::TLS::TLS_Data_Reader::get_range_vector(), Botan::TLS::Alert::HANDSHAKE_FAILURE, Botan::TLS::Protocol_Version::is_datagram_protocol(), offered_suite(), and Botan::TLS::TLS_EMPTY_RENEGOTIATION_INFO_SCSV.

285  {
286  if(buf.size() < 41)
287  throw Decoding_Error("Client_Hello: Packet corrupted");
288 
289  TLS_Data_Reader reader("ClientHello", buf);
290 
291  const uint8_t major_version = reader.get_byte();
292  const uint8_t minor_version = reader.get_byte();
293 
294  m_version = Protocol_Version(major_version, minor_version);
295 
296  m_random = reader.get_fixed<uint8_t>(32);
297 
298  m_session_id = reader.get_range<uint8_t>(1, 0, 32);
299 
300  if(m_version.is_datagram_protocol())
301  m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
302 
303  m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
304 
305  m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
306 
307  m_extensions.deserialize(reader, Connection_Side::CLIENT);
308 
309  if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
310  {
311  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
312  {
313  if(!reneg->renegotiation_info().empty())
314  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
315  "Client sent renegotiation SCSV and non-empty extension");
316  }
317  else
318  {
319  // add fake extension
320  m_extensions.add(new Renegotiation_Extension());
321  }
322  }
323  }
void add(Extension *extn)
void deserialize(TLS_Data_Reader &reader, Connection_Side from)
bool offered_suite(uint16_t ciphersuite) const

Member Function Documentation

◆ ciphersuites()

const std::vector<uint16_t>& Botan::TLS::Client_Hello::ciphersuites ( ) const
inline

Definition at line 105 of file tls_messages.h.

105 { return m_suites; }

◆ compression_methods()

const std::vector<uint8_t>& Botan::TLS::Client_Hello::compression_methods ( ) const
inline

Definition at line 103 of file tls_messages.h.

103 { return m_comp_methods; }

◆ cookie()

const std::vector<uint8_t>& Botan::TLS::Client_Hello::cookie ( ) const
inline

Definition at line 149 of file tls_messages.h.

149 { return m_hello_cookie; }

◆ cookie_input_data()

std::vector< uint8_t > Botan::TLS::Client_Hello::cookie_input_data ( ) const

Definition at line 262 of file msg_client_hello.cpp.

References Botan::TLS::append_tls_length_value(), Botan::TLS::Protocol_Version::major_version(), and Botan::TLS::Protocol_Version::minor_version().

263  {
264  std::vector<uint8_t> buf;
265 
266  buf.push_back(m_version.major_version());
267  buf.push_back(m_version.minor_version());
268  buf += m_random;
269 
270  append_tls_length_value(buf, m_session_id, 1);
271 
272  append_tls_length_value(buf, m_suites, 2);
273  append_tls_length_value(buf, m_comp_methods, 1);
274 
275  // Here we don't serialize the extensions since the client extensions
276  // may contain values we don't know how to serialize back.
277 
278  return buf;
279  }
uint8_t minor_version() const
Definition: tls_version.h:84
uint8_t major_version() const
Definition: tls_version.h:79
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition: tls_reader.h:185

◆ extension_types()

std::set<Handshake_Extension_Type> Botan::TLS::Client_Hello::extension_types ( ) const
inline

Definition at line 153 of file tls_messages.h.

Referenced by Botan::TLS::Server_Hello::Server_Hello().

154  { return m_extensions.extension_types(); }
std::set< Handshake_Extension_Type > extension_types() const

◆ extensions()

const Extensions& Botan::TLS::Client_Hello::extensions ( ) const
inline

Definition at line 156 of file tls_messages.h.

156 { return m_extensions; }

◆ next_protocols()

std::vector< std::string > Botan::TLS::Client_Hello::next_protocols ( ) const

Definition at line 448 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

Referenced by Client_Hello().

449  {
450  if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
451  return alpn->protocols();
452  return std::vector<std::string>();
453  }

◆ offered_suite()

bool Botan::TLS::Client_Hello::offered_suite ( uint16_t  ciphersuite) const

Definition at line 333 of file msg_client_hello.cpp.

Referenced by Client_Hello(), and sent_fallback_scsv().

334  {
335  for(size_t i = 0; i != m_suites.size(); ++i)
336  if(m_suites[i] == ciphersuite)
337  return true;
338  return false;
339  }

◆ prefers_compressed_ec_points()

bool Botan::TLS::Client_Hello::prefers_compressed_ec_points ( ) const

Definition at line 367 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

368  {
369  if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
370  {
371  return ecc_formats->prefers_compressed();
372  }
373  return false;
374  }

◆ random()

const std::vector<uint8_t>& Botan::TLS::Client_Hello::random ( ) const
inline

Definition at line 99 of file tls_messages.h.

99 { return m_random; }

◆ renegotiation_info()

std::vector< uint8_t > Botan::TLS::Client_Hello::renegotiation_info ( ) const

Definition at line 397 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

Referenced by Botan::TLS::Channel::secure_renegotiation_check().

398  {
399  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
400  return reneg->renegotiation_info();
401  return std::vector<uint8_t>();
402  }

◆ secure_renegotiation()

bool Botan::TLS::Client_Hello::secure_renegotiation ( ) const

Definition at line 392 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::has().

Referenced by Botan::TLS::Channel::secure_renegotiation_check(), and Botan::TLS::Server_Hello::Server_Hello().

393  {
394  return m_extensions.has<Renegotiation_Extension>();
395  }

◆ sent_fallback_scsv()

bool Botan::TLS::Client_Hello::sent_fallback_scsv ( ) const

Definition at line 325 of file msg_client_hello.cpp.

References offered_suite(), and Botan::TLS::TLS_FALLBACK_SCSV.

326  {
327  return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
328  }
bool offered_suite(uint16_t ciphersuite) const

◆ sent_signature_algorithms()

bool Botan::TLS::Client_Hello::sent_signature_algorithms ( ) const

Definition at line 443 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::has().

444  {
445  return m_extensions.has<Signature_Algorithms>();
446  }

◆ session_id()

const std::vector<uint8_t>& Botan::TLS::Client_Hello::session_id ( ) const
inline

Definition at line 101 of file tls_messages.h.

101 { return m_session_id; }

◆ session_ticket()

std::vector< uint8_t > Botan::TLS::Client_Hello::session_ticket ( ) const

Definition at line 416 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

Referenced by Botan::TLS::Handshake_State::session_ticket().

417  {
418  if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
419  return ticket->contents();
420  return std::vector<uint8_t>();
421  }

◆ signature_schemes()

std::vector< Signature_Scheme > Botan::TLS::Client_Hello::signature_schemes ( ) const

Definition at line 341 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

Referenced by Botan::TLS::Handshake_State::choose_sig_format(), and Botan::TLS::Handshake_State::parse_sig_format().

342  {
343  std::vector<Signature_Scheme> schemes;
344 
345  if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
346  {
347  schemes = sigs->supported_schemes();
348  }
349 
350  return schemes;
351  }

◆ sni_hostname()

std::string Botan::TLS::Client_Hello::sni_hostname ( ) const

Definition at line 376 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

377  {
378  if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
379  return sni->host_name();
380  return "";
381  }

◆ srtp_profiles()

std::vector< uint16_t > Botan::TLS::Client_Hello::srtp_profiles ( ) const

Definition at line 455 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

Referenced by Botan::TLS::Server_Hello::Server_Hello().

456  {
457  if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
458  return srtp->profiles();
459  return std::vector<uint16_t>();
460  }

◆ supported_dh_groups()

std::vector< Group_Params > Botan::TLS::Client_Hello::supported_dh_groups ( ) const

Definition at line 360 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

361  {
362  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
363  return groups->dh_groups();
364  return std::vector<Group_Params>();
365  }

◆ supported_ecc_curves()

std::vector< Group_Params > Botan::TLS::Client_Hello::supported_ecc_curves ( ) const

Definition at line 353 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

354  {
355  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
356  return groups->ec_groups();
357  return std::vector<Group_Params>();
358  }

◆ supported_versions()

std::vector< Protocol_Version > Botan::TLS::Client_Hello::supported_versions ( ) const

Definition at line 404 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::get().

405  {
406  if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
407  return versions->versions();
408  return {};
409  }

◆ supports_alpn()

bool Botan::TLS::Client_Hello::supports_alpn ( ) const

Definition at line 423 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::has().

Referenced by Botan::TLS::Server_Hello::Server_Hello().

424  {
425  return m_extensions.has<Application_Layer_Protocol_Notification>();
426  }

◆ supports_cert_status_message()

bool Botan::TLS::Client_Hello::supports_cert_status_message ( ) const

Definition at line 433 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::has().

Referenced by Botan::TLS::Server_Hello::Server_Hello().

434  {
435  return m_extensions.has<Certificate_Status_Request>();
436  }

◆ supports_encrypt_then_mac()

bool Botan::TLS::Client_Hello::supports_encrypt_then_mac ( ) const

Definition at line 438 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::has().

Referenced by Botan::TLS::Server_Hello::Server_Hello().

439  {
440  return m_extensions.has<Encrypt_then_MAC>();
441  }

◆ supports_extended_master_secret()

bool Botan::TLS::Client_Hello::supports_extended_master_secret ( ) const

Definition at line 428 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::has().

Referenced by Botan::TLS::Server_Hello::Server_Hello().

429  {
430  return m_extensions.has<Extended_Master_Secret>();
431  }

◆ supports_session_ticket()

bool Botan::TLS::Client_Hello::supports_session_ticket ( ) const

Definition at line 411 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::has().

Referenced by Botan::TLS::Server_Hello::Server_Hello().

412  {
413  return m_extensions.has<Session_Ticket>();
414  }

◆ type()

Handshake_Type Botan::TLS::Client_Hello::type ( ) const
inlineoverridevirtual
Returns
the message type

Implements Botan::TLS::Handshake_Message.

Definition at line 93 of file tls_messages.h.

References Botan::TLS::CLIENT_HELLO.

◆ type_string()

std::string Botan::TLS::Handshake_Message::type_string ( ) const
inherited
Returns
string representation of this message type

Definition at line 19 of file tls_handshake_state.cpp.

References Botan::TLS::handshake_type_to_string(), and Botan::TLS::Handshake_Message::type().

20  {
22  }
virtual Handshake_Type type() const =0
const char * handshake_type_to_string(Handshake_Type type)

◆ update_hello_cookie()

void Botan::TLS::Client_Hello::update_hello_cookie ( const Hello_Verify_Request hello_verify)

Definition at line 224 of file msg_client_hello.cpp.

References Botan::TLS::Hello_Verify_Request::cookie(), and Botan::TLS::Protocol_Version::is_datagram_protocol().

225  {
226  if(!m_version.is_datagram_protocol())
227  throw Invalid_State("Cannot use hello cookie with stream protocol");
228 
229  m_hello_cookie = hello_verify.cookie();
230  }

◆ version()

Protocol_Version Botan::TLS::Client_Hello::version ( ) const
inline

Definition at line 95 of file tls_messages.h.

95 { return m_version; }

The documentation for this class was generated from the following files: