Botan  2.4.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, 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, 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
 
std::set< Handshake_Extension_Typeextension_types () 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::string sni_hostname () const
 
std::vector< uint16_t > srtp_profiles () const
 
std::vector< std::pair< std::string, std::string > > supported_algos () const
 
std::vector< std::string > supported_dh_groups () const
 
std::vector< std::string > supported_ecc_curves () const
 
std::set< std::string > supported_sig_algos () 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 68 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,
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 81 of file msg_client_hello.cpp.

References Botan::TLS::Policy::acceptable_protocol_version(), Botan::TLS::Extensions::add(), Botan::TLS::Policy::allowed_groups(), Botan::TLS::Policy::allowed_signature_hashes(), Botan::TLS::Policy::allowed_signature_methods(), BOTAN_ASSERT, Botan::TLS::Supported_Groups::curves(), Botan::TLS::Client_Hello::Settings::hostname(), Botan::TLS::Protocol_Version::is_datagram_protocol(), Botan::TLS::Policy::negotiate_encrypt_then_mac(), 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::Handshake_Hash::update(), and Botan::TLS::Policy::use_ecc_point_compression().

87  :
88  m_version(client_settings.protocol_version()),
89  m_random(make_hello_random(rng, policy)),
90  m_suites(policy.ciphersuite_list(m_version, !client_settings.srp_identifier().empty())),
91  m_comp_methods(policy.compression())
92  {
93  BOTAN_ASSERT(policy.acceptable_protocol_version(client_settings.protocol_version()),
94  "Our policy accepts the version we are offering");
95 
96  /*
97  * Place all empty extensions in front to avoid a bug in some systems
98  * which reject hellos when the last extension in the list is empty.
99  */
100  m_extensions.add(new Extended_Master_Secret);
101  m_extensions.add(new Session_Ticket());
102 
103  if(policy.negotiate_encrypt_then_mac())
104  m_extensions.add(new Encrypt_then_MAC);
105 
106  m_extensions.add(new Renegotiation_Extension(reneg_info));
107  m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
108 
109  if(policy.support_cert_status_message())
110  m_extensions.add(new Certificate_Status_Request({}, {}));
111 
112  if(reneg_info.empty() && !next_protocols.empty())
113  m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
114 
116  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
117  policy.allowed_signature_methods()));
118 
119  if(m_version.is_datagram_protocol())
120  m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
121 
122 #if defined(BOTAN_HAS_SRP6)
123  m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
124 #else
125  if(!client_settings.srp_identifier().empty())
126  {
127  throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
128  }
129 #endif
130 
131  Supported_Groups* supported_groups = new Supported_Groups(policy.allowed_groups());
132  m_extensions.add(supported_groups);
133 
134  if(!supported_groups->curves().empty())
135  {
136  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
137  }
138 
140  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
141  policy.allowed_signature_methods()));
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:29
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,
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_ecc_curves(), Botan::TLS::Policy::allowed_signature_hashes(), Botan::TLS::Policy::allowed_signature_methods(), Botan::TLS::Session::ciphersuite_code(), Botan::TLS::Session::compression_method(), Botan::TLS::Server_Information::hostname(), 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::Handshake_Hash::update(), Botan::TLS::Policy::use_ecc_point_compression(), and Botan::value_exists().

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

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

99 { return m_suites; }

◆ compression_methods()

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

Definition at line 101 of file tls_messages.h.

101 { return m_comp_methods; }

◆ extension_types()

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

Definition at line 147 of file tls_messages.h.

References hash.

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

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

◆ next_protocols()

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

Definition at line 420 of file msg_client_hello.cpp.

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

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

◆ offered_suite()

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

Definition at line 309 of file msg_client_hello.cpp.

Referenced by Client_Hello(), and sent_fallback_scsv().

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

◆ prefers_compressed_ec_points()

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

Definition at line 346 of file msg_client_hello.cpp.

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

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

◆ random()

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

Definition at line 95 of file tls_messages.h.

95 { return m_random; }

◆ renegotiation_info()

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

Definition at line 376 of file msg_client_hello.cpp.

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

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

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

◆ secure_renegotiation()

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

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

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

◆ sent_fallback_scsv()

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

Definition at line 301 of file msg_client_hello.cpp.

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

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

◆ sent_signature_algorithms()

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

Definition at line 415 of file msg_client_hello.cpp.

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

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

◆ session_id()

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

Definition at line 97 of file tls_messages.h.

97 { return m_session_id; }

◆ session_ticket()

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

Definition at line 388 of file msg_client_hello.cpp.

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

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

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

◆ sni_hostname()

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

Definition at line 355 of file msg_client_hello.cpp.

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

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

◆ srtp_profiles()

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

Definition at line 427 of file msg_client_hello.cpp.

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

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

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

◆ supported_algos()

std::vector< std::pair< std::string, std::string > > Botan::TLS::Client_Hello::supported_algos ( ) const

Definition at line 317 of file msg_client_hello.cpp.

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

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

318  {
319  if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
320  return sigs->supported_signature_algorthms();
321  return std::vector<std::pair<std::string, std::string>>();
322  }

◆ supported_dh_groups()

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

Definition at line 339 of file msg_client_hello.cpp.

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

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

◆ supported_ecc_curves()

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

Definition at line 332 of file msg_client_hello.cpp.

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

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

◆ supported_sig_algos()

std::set< std::string > Botan::TLS::Client_Hello::supported_sig_algos ( ) const

Definition at line 324 of file msg_client_hello.cpp.

References supported_algos().

325  {
326  std::set<std::string> sig;
327  for(auto&& hash_and_sig : supported_algos())
328  sig.insert(hash_and_sig.second);
329  return sig;
330  }
std::vector< std::pair< std::string, std::string > > supported_algos() const

◆ supports_alpn()

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

Definition at line 395 of file msg_client_hello.cpp.

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

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

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

◆ supports_cert_status_message()

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

Definition at line 405 of file msg_client_hello.cpp.

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

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

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

◆ supports_encrypt_then_mac()

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

Definition at line 410 of file msg_client_hello.cpp.

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

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

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

◆ supports_extended_master_secret()

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

Definition at line 400 of file msg_client_hello.cpp.

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

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

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

◆ supports_session_ticket()

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

Definition at line 383 of file msg_client_hello.cpp.

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

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

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

◆ type()

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

Implements Botan::TLS::Handshake_Message.

Definition at line 91 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 210 of file msg_client_hello.cpp.

References Botan::TLS::append_tls_length_value(), Botan::TLS::Hello_Verify_Request::cookie(), Botan::TLS::Protocol_Version::is_datagram_protocol(), Botan::TLS::Protocol_Version::major_version(), Botan::TLS::Protocol_Version::minor_version(), and Botan::TLS::Extensions::serialize().

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

◆ version()

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

Definition at line 93 of file tls_messages.h.

93 { return m_version; }

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