Botan  2.1.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

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)
 
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_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 67 of file tls_messages.h.

Constructor & Destructor Documentation

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

References Botan::TLS::Policy::acceptable_protocol_version(), Botan::TLS::Extensions::add(), Botan::TLS::Policy::allowed_ecc_curves(), Botan::TLS::Policy::allowed_signature_hashes(), Botan::TLS::Policy::allowed_signature_methods(), BOTAN_ASSERT, 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::Protocol_Version::supports_negotiable_signature_algorithms(), Botan::TLS::TLS_FALLBACK_SCSV, Botan::TLS::Handshake_Hash::update(), and Botan::TLS::Policy::use_ecc_point_compression().

79  :
80  m_version(client_settings.protocol_version()),
81  m_random(make_hello_random(rng, policy)),
82  m_suites(policy.ciphersuite_list(m_version, !client_settings.srp_identifier().empty())),
83  m_comp_methods(policy.compression())
84  {
85  BOTAN_ASSERT(policy.acceptable_protocol_version(client_settings.protocol_version()),
86  "Our policy accepts the version we are offering");
87 
88  /*
89  * Place all empty extensions in front to avoid a bug in some systems
90  * which reject hellos when the last extension in the list is empty.
91  */
92  m_extensions.add(new Extended_Master_Secret);
93  m_extensions.add(new Session_Ticket());
94  m_extensions.add(new Certificate_Status_Request);
95 
96  if(policy.negotiate_encrypt_then_mac())
97  m_extensions.add(new Encrypt_then_MAC);
98 
99  m_extensions.add(new Renegotiation_Extension(reneg_info));
100  m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
101 
102  m_extensions.add(new Certificate_Status_Request({}, {}));
103 
104  if(reneg_info.empty() && !next_protocols.empty())
105  m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
106 
108  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
109  policy.allowed_signature_methods()));
110 
111  if(m_version.is_datagram_protocol())
112  m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
113 
114 #if defined(BOTAN_HAS_SRP6)
115  m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
116 #else
117  if(!client_settings.srp_identifier().empty())
118  {
119  throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
120  }
121 #endif
122 
123  m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves()));
124 
125  if(!policy.allowed_ecc_curves().empty())
126  {
127  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
128  }
129 
131  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
132  policy.allowed_signature_methods()));
133 
134  if(policy.send_fallback_scsv(client_settings.protocol_version()))
135  m_suites.push_back(TLS_FALLBACK_SCSV);
136 
137  hash.update(io.send(*this));
138  }
void add(Extension *extn)
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
std::vector< std::string > next_protocols() const
Definition: tls_messages.h:202
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, const Policy &policy)
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:61
bool is_datagram_protocol() const
Definition: tls_version.cpp:34
MechanismType hash
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 143 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().

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

Definition at line 243 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.

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

Member Function Documentation

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

Definition at line 98 of file tls_messages.h.

98 { return m_suites; }
std::vector<uint8_t> Botan::TLS::Client_Hello::compression_methods ( ) const
inline

Definition at line 100 of file tls_messages.h.

100 { return m_comp_methods; }
std::set<Handshake_Extension_Type> Botan::TLS::Client_Hello::extension_types ( ) const
inline

Definition at line 218 of file tls_messages.h.

219  { return m_extensions.extension_types(); }
std::set< Handshake_Extension_Type > extension_types() const
std::vector<std::string> Botan::TLS::Client_Hello::next_protocols ( ) const
inline

Definition at line 202 of file tls_messages.h.

203  {
204  if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
205  return alpn->protocols();
206  return std::vector<std::string>();
207  }
bool Botan::TLS::Client_Hello::offered_suite ( uint16_t  ciphersuite) const

Definition at line 301 of file msg_client_hello.cpp.

Referenced by Client_Hello(), and sent_fallback_scsv().

302  {
303  for(size_t i = 0; i != m_suites.size(); ++i)
304  if(m_suites[i] == ciphersuite)
305  return true;
306  return false;
307  }
bool Botan::TLS::Client_Hello::prefers_compressed_ec_points ( ) const
inline

Definition at line 128 of file tls_messages.h.

129  {
130  if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
131  {
132  return ecc_formats->prefers_compressed();
133  }
134  return false;
135  }
const std::vector<uint8_t>& Botan::TLS::Client_Hello::random ( ) const
inline

Definition at line 94 of file tls_messages.h.

94 { return m_random; }
std::vector<uint8_t> Botan::TLS::Client_Hello::renegotiation_info ( ) const
inline

Definition at line 158 of file tls_messages.h.

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

159  {
160  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
161  return reneg->renegotiation_info();
162  return std::vector<uint8_t>();
163  }
bool Botan::TLS::Client_Hello::secure_renegotiation ( ) const
inline

Definition at line 153 of file tls_messages.h.

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

154  {
155  return m_extensions.has<Renegotiation_Extension>();
156  }
bool Botan::TLS::Client_Hello::sent_fallback_scsv ( ) const

Definition at line 293 of file msg_client_hello.cpp.

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

294  {
295  return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
296  }
bool offered_suite(uint16_t ciphersuite) const
bool Botan::TLS::Client_Hello::sent_signature_algorithms ( ) const
inline

Definition at line 197 of file tls_messages.h.

198  {
199  return m_extensions.has<Signature_Algorithms>();
200  }
const std::vector<uint8_t>& Botan::TLS::Client_Hello::session_id ( ) const
inline

Definition at line 96 of file tls_messages.h.

96 { return m_session_id; }
std::vector<uint8_t> Botan::TLS::Client_Hello::session_ticket ( ) const
inline

Definition at line 170 of file tls_messages.h.

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

171  {
172  if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
173  return ticket->contents();
174  return std::vector<uint8_t>();
175  }
std::string Botan::TLS::Client_Hello::sni_hostname ( ) const
inline

Definition at line 137 of file tls_messages.h.

138  {
139  if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
140  return sni->host_name();
141  return "";
142  }
std::vector<uint16_t> Botan::TLS::Client_Hello::srtp_profiles ( ) const
inline

Definition at line 209 of file tls_messages.h.

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

210  {
211  if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
212  return srtp->profiles();
213  return std::vector<uint16_t>();
214  }
std::vector<std::pair<std::string, std::string> > Botan::TLS::Client_Hello::supported_algos ( ) const
inline

Definition at line 106 of file tls_messages.h.

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

107  {
108  if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
109  return sigs->supported_signature_algorthms();
110  return std::vector<std::pair<std::string, std::string>>();
111  }
std::vector<std::string> Botan::TLS::Client_Hello::supported_ecc_curves ( ) const
inline

Definition at line 121 of file tls_messages.h.

122  {
123  if(Supported_Elliptic_Curves* ecc = m_extensions.get<Supported_Elliptic_Curves>())
124  return ecc->curves();
125  return std::vector<std::string>();
126  }
std::set<std::string> Botan::TLS::Client_Hello::supported_sig_algos ( ) const
inline

Definition at line 113 of file tls_messages.h.

114  {
115  std::set<std::string> sig;
116  for(auto&& hash_and_sig : supported_algos())
117  sig.insert(hash_and_sig.second);
118  return sig;
119  }
std::vector< std::pair< std::string, std::string > > supported_algos() const
Definition: tls_messages.h:106
bool Botan::TLS::Client_Hello::supports_alpn ( ) const
inline

Definition at line 177 of file tls_messages.h.

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

178  {
179  return m_extensions.has<Application_Layer_Protocol_Notification>();
180  }
bool Botan::TLS::Client_Hello::supports_cert_status_message ( ) const
inline

Definition at line 187 of file tls_messages.h.

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

188  {
189  return m_extensions.has<Certificate_Status_Request>();
190  }
bool Botan::TLS::Client_Hello::supports_encrypt_then_mac ( ) const
inline

Definition at line 192 of file tls_messages.h.

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

193  {
194  return m_extensions.has<Encrypt_then_MAC>();
195  }
bool Botan::TLS::Client_Hello::supports_extended_master_secret ( ) const
inline

Definition at line 182 of file tls_messages.h.

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

183  {
184  return m_extensions.has<Extended_Master_Secret>();
185  }
bool Botan::TLS::Client_Hello::supports_session_ticket ( ) const
inline

Definition at line 165 of file tls_messages.h.

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

166  {
167  return m_extensions.has<Session_Ticket>();
168  }
Handshake_Type Botan::TLS::Client_Hello::type ( ) const
inlineoverridevirtual
Returns
the message type

Implements Botan::TLS::Handshake_Message.

Definition at line 90 of file tls_messages.h.

References Botan::TLS::CLIENT_HELLO.

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

Definition at line 17 of file tls_handshake_state.cpp.

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

18  {
20  }
virtual Handshake_Type type() const =0
const char * handshake_type_to_string(Handshake_Type type)
void Botan::TLS::Client_Hello::update_hello_cookie ( const Hello_Verify_Request hello_verify)

Definition at line 202 of file msg_client_hello.cpp.

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

203  {
204  if(!m_version.is_datagram_protocol())
205  throw Exception("Cannot use hello cookie with stream protocol");
206 
207  m_hello_cookie = hello_verify.cookie();
208  }
bool is_datagram_protocol() const
Definition: tls_version.cpp:34
Protocol_Version Botan::TLS::Client_Hello::version ( ) const
inline

Definition at line 92 of file tls_messages.h.

92 { return m_version; }

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