Botan  2.8.0
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)
 
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
 
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_ASSERT, 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(), 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  BOTAN_ASSERT(policy.acceptable_protocol_version(client_settings.protocol_version()),
96  "Our policy accepts the version we are offering");
97 
98  /*
99  * Place all empty extensions in front to avoid a bug in some systems
100  * which reject hellos when the last extension in the list is empty.
101  */
102  m_extensions.add(new Extended_Master_Secret);
103  m_extensions.add(new Session_Ticket());
104 
105  if(policy.negotiate_encrypt_then_mac())
106  m_extensions.add(new Encrypt_then_MAC);
107 
108  m_extensions.add(new Renegotiation_Extension(reneg_info));
109  m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
110 
111  if(policy.support_cert_status_message())
112  m_extensions.add(new Certificate_Status_Request({}, {}));
113 
114  if(reneg_info.empty() && !next_protocols.empty())
115  m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
116 
118  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
119 
120  if(m_version.is_datagram_protocol())
121  m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
122 
123 #if defined(BOTAN_HAS_SRP6)
124  m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
125 #else
126  if(!client_settings.srp_identifier().empty())
127  {
128  throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
129  }
130 #endif
131 
132  std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
133 
134  if(supported_groups->ec_groups().size() > 0)
135  {
136  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
137  }
138 
139  m_extensions.add(supported_groups.release());
140 
141  cb.tls_modify_extensions(m_extensions, CLIENT);
142 
143  if(policy.send_fallback_scsv(client_settings.protocol_version()))
144  m_suites.push_back(TLS_FALLBACK_SCSV);
145 
146  hash.update(io.send(*this));
147  }
void add(Extension *extn)
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
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 152 of file msg_client_hello.cpp.

References 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::Session::supports_encrypt_then_mac(), Botan::TLS::Protocol_Version::supports_negotiable_signature_algorithms(), Botan::TLS::Callbacks::tls_modify_extensions(), Botan::TLS::Policy::use_ecc_point_compression(), and Botan::value_exists().

159  :
160  m_version(session.version()),
161  m_session_id(session.session_id()),
162  m_random(make_hello_random(rng, policy)),
163  m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))),
164  m_comp_methods(1)
165  {
166  if(!value_exists(m_suites, session.ciphersuite_code()))
167  m_suites.push_back(session.ciphersuite_code());
168 
169  /*
170  We always add the EMS extension, even if not used in the original session.
171  If the server understands it and follows the RFC it should reject our resume
172  attempt and upgrade us to a new session with the EMS protection.
173  */
174  m_extensions.add(new Extended_Master_Secret);
175 
176  m_extensions.add(new Renegotiation_Extension(reneg_info));
177  m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
178  m_extensions.add(new Session_Ticket(session.session_ticket()));
179 
180  std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
181 
182  if(supported_groups->ec_groups().size() > 0)
183  {
184  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
185  }
186 
187  m_extensions.add(supported_groups.release());
188 
189  if(session.supports_encrypt_then_mac())
190  m_extensions.add(new Encrypt_then_MAC);
191 
192 #if defined(BOTAN_HAS_SRP6)
193  m_extensions.add(new SRP_Identifier(session.srp_identifier()));
194 #else
195  if(!session.srp_identifier().empty())
196  {
197  throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled");
198  }
199 #endif
200 
202  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
203 
204  if(reneg_info.empty() && !next_protocols.empty())
205  m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
206 
207  cb.tls_modify_extensions(m_extensions, CLIENT);
208 
209  hash.update(io.send(*this));
210  }
void add(Extension *extn)
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
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 253 of file msg_client_hello.cpp.

References Botan::TLS::Extensions::add(), 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::Extensions::has(), Botan::TLS::Protocol_Version::is_datagram_protocol(), offered_suite(), Botan::TLS::Protocol_Version::supports_negotiable_signature_algorithms(), and Botan::TLS::TLS_EMPTY_RENEGOTIATION_INFO_SCSV.

254  {
255  if(buf.size() < 41)
256  throw Decoding_Error("Client_Hello: Packet corrupted");
257 
258  TLS_Data_Reader reader("ClientHello", buf);
259 
260  const uint8_t major_version = reader.get_byte();
261  const uint8_t minor_version = reader.get_byte();
262 
263  m_version = Protocol_Version(major_version, minor_version);
264 
265  m_random = reader.get_fixed<uint8_t>(32);
266 
267  m_session_id = reader.get_range<uint8_t>(1, 0, 32);
268 
269  if(m_version.is_datagram_protocol())
270  m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
271 
272  m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
273 
274  m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
275 
276  m_extensions.deserialize(reader);
277 
278  if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
279  {
280  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
281  {
282  if(!reneg->renegotiation_info().empty())
283  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
284  "Client sent renegotiation SCSV and non-empty extension");
285  }
286  else
287  {
288  // add fake extension
289  m_extensions.add(new Renegotiation_Extension());
290  }
291  }
292 
293  // Parsing complete, now any additional decoding checks
294 
295  if(m_version.supports_negotiable_signature_algorithms() == false)
296  {
297  if(m_extensions.has<Signature_Algorithms>())
298  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
299  "Client sent signature_algorithms extension in version that doesn't support it");
300  }
301  }
void add(Extension *extn)
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
bool offered_suite(uint16_t ciphersuite) const
void deserialize(TLS_Data_Reader &reader)

Member Function Documentation

◆ ciphersuites()

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

Definition at line 101 of file tls_messages.h.

101 { return m_suites; }

◆ extension_types()

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

Definition at line 145 of file tls_messages.h.

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

146  { 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 148 of file tls_messages.h.

148 { return m_extensions; }

◆ next_protocols()

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

Definition at line 419 of file msg_client_hello.cpp.

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

Referenced by Client_Hello().

420  {
421  if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
422  return alpn->protocols();
423  return std::vector<std::string>();
424  }

◆ offered_suite()

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

Definition at line 311 of file msg_client_hello.cpp.

Referenced by Client_Hello(), and sent_fallback_scsv().

312  {
313  for(size_t i = 0; i != m_suites.size(); ++i)
314  if(m_suites[i] == ciphersuite)
315  return true;
316  return false;
317  }

◆ prefers_compressed_ec_points()

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

Definition at line 345 of file msg_client_hello.cpp.

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

346  {
347  if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
348  {
349  return ecc_formats->prefers_compressed();
350  }
351  return false;
352  }

◆ random()

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

Definition at line 97 of file tls_messages.h.

97 { return m_random; }

◆ renegotiation_info()

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

Definition at line 375 of file msg_client_hello.cpp.

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

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

376  {
377  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
378  return reneg->renegotiation_info();
379  return std::vector<uint8_t>();
380  }

◆ secure_renegotiation()

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

Definition at line 370 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().

371  {
372  return m_extensions.has<Renegotiation_Extension>();
373  }

◆ sent_fallback_scsv()

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

Definition at line 303 of file msg_client_hello.cpp.

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

304  {
305  return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
306  }
bool offered_suite(uint16_t ciphersuite) const

◆ sent_signature_algorithms()

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

Definition at line 414 of file msg_client_hello.cpp.

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

415  {
416  return m_extensions.has<Signature_Algorithms>();
417  }

◆ session_id()

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

Definition at line 99 of file tls_messages.h.

99 { return m_session_id; }

◆ session_ticket()

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

Definition at line 387 of file msg_client_hello.cpp.

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

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

388  {
389  if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
390  return ticket->contents();
391  return std::vector<uint8_t>();
392  }

◆ signature_schemes()

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

Definition at line 319 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().

320  {
321  std::vector<Signature_Scheme> schemes;
322 
323  if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
324  {
325  schemes = sigs->supported_schemes();
326  }
327 
328  return schemes;
329  }

◆ sni_hostname()

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

Definition at line 354 of file msg_client_hello.cpp.

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

355  {
356  if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
357  return sni->host_name();
358  return "";
359  }

◆ srtp_profiles()

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

Definition at line 426 of file msg_client_hello.cpp.

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

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

427  {
428  if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
429  return srtp->profiles();
430  return std::vector<uint16_t>();
431  }

◆ supported_dh_groups()

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

Definition at line 338 of file msg_client_hello.cpp.

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

339  {
340  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
341  return groups->dh_groups();
342  return std::vector<Group_Params>();
343  }

◆ supported_ecc_curves()

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

Definition at line 331 of file msg_client_hello.cpp.

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

332  {
333  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
334  return groups->ec_groups();
335  return std::vector<Group_Params>();
336  }

◆ supports_alpn()

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

Definition at line 394 of file msg_client_hello.cpp.

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

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

395  {
396  return m_extensions.has<Application_Layer_Protocol_Notification>();
397  }

◆ supports_cert_status_message()

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

Definition at line 404 of file msg_client_hello.cpp.

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

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

405  {
406  return m_extensions.has<Certificate_Status_Request>();
407  }

◆ supports_encrypt_then_mac()

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

Definition at line 409 of file msg_client_hello.cpp.

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

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

410  {
411  return m_extensions.has<Encrypt_then_MAC>();
412  }

◆ supports_extended_master_secret()

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

Definition at line 399 of file msg_client_hello.cpp.

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

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

400  {
401  return m_extensions.has<Extended_Master_Secret>();
402  }

◆ supports_session_ticket()

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

Definition at line 382 of file msg_client_hello.cpp.

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

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

383  {
384  return m_extensions.has<Session_Ticket>();
385  }

◆ 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 212 of file msg_client_hello.cpp.

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

213  {
214  if(!m_version.is_datagram_protocol())
215  throw Exception("Cannot use hello cookie with stream protocol");
216 
217  m_hello_cookie = hello_verify.cookie();
218  }

◆ 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: