Botan  2.1.0
Crypto and TLS for C++11
Public Member Functions | List of all members
Botan::TLS::Server_Key_Exchange Class Referencefinal

#include <tls_messages.h>

Inheritance diagram for Botan::TLS::Server_Key_Exchange:
Botan::TLS::Handshake_Message

Public Member Functions

const std::vector< uint8_t > & params () const
 
const Private_Keyserver_kex_key () const
 
 Server_Key_Exchange (Handshake_IO &io, Handshake_State &state, const Policy &policy, Credentials_Manager &creds, RandomNumberGenerator &rng, const Private_Key *signing_key=nullptr)
 
 Server_Key_Exchange (const std::vector< uint8_t > &buf, const std::string &kex_alg, const std::string &sig_alg, Protocol_Version version)
 
Handshake_Type type () const override
 
std::string type_string () const
 
bool verify (const Public_Key &server_key, const Handshake_State &state, const Policy &policy) const
 
 ~Server_Key_Exchange ()=default
 

Detailed Description

Server Key Exchange Message

Definition at line 581 of file tls_messages.h.

Constructor & Destructor Documentation

Botan::TLS::Server_Key_Exchange::Server_Key_Exchange ( Handshake_IO io,
Handshake_State state,
const Policy policy,
Credentials_Manager creds,
RandomNumberGenerator rng,
const Private_Key signing_key = nullptr 
)

Create a new Server Key Exchange message

Definition at line 40 of file msg_server_kex.cpp.

References Botan::TLS::append_tls_length_value(), BOTAN_ASSERT, Botan::CECPQ1_offer(), Botan::CECPQ1_OFFER_BYTES, Botan::TLS::Policy::choose_curve(), Botan::TLS::Handshake_State::choose_sig_format(), Botan::TLS::Handshake_State::ciphersuite(), Botan::TLS::Handshake_State::client_hello(), Botan::PointGFp::COMPRESSED, Botan::TLS::Policy::dh_group(), Botan::BigInt::encode(), Botan::get_byte(), Botan::DL_Group::get_g(), Botan::DL_Group::get_p(), Botan::TLS::Alert::HANDSHAKE_FAILURE, Botan::TLS::Handshake_State::hash(), Botan::TLS::Policy::hide_unknown_users(), Botan::TLS::Ciphersuite::kex_algo(), Botan::TLS::Supported_Elliptic_Curves::name_to_curve_id(), params(), Botan::Credentials_Manager::psk_identity_hint(), Botan::TLS::Handshake_IO::send(), Botan::TLS::Handshake_State::server_hello(), Botan::TLS::Ciphersuite::sig_algo(), Botan::PK_Signer::signature(), Botan::Credentials_Manager::srp_verifier(), Botan::PointGFp::UNCOMPRESSED, Botan::TLS::Alert::UNKNOWN_PSK_IDENTITY, Botan::TLS::Handshake_Hash::update(), and Botan::PK_Signer::update().

46  {
47  const std::string hostname = state.client_hello()->sni_hostname();
48  const std::string kex_algo = state.ciphersuite().kex_algo();
49 
50  if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
51  {
52  std::string identity_hint =
53  creds.psk_identity_hint("tls-server", hostname);
54 
55  append_tls_length_value(m_params, identity_hint, 2);
56  }
57 
58  if(kex_algo == "DH" || kex_algo == "DHE_PSK")
59  {
60  std::unique_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, DL_Group(policy.dh_group())));
61 
62  append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_p()), 2);
63  append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_g()), 2);
64  append_tls_length_value(m_params, dh->public_value(), 2);
65  m_kex_key.reset(dh.release());
66  }
67  else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
68  {
69  const std::vector<std::string>& curves =
70  state.client_hello()->supported_ecc_curves();
71 
72  if(curves.empty())
73  throw Internal_Error("Client sent no ECC extension but we negotiated ECDH");
74 
75  const std::string curve_name = policy.choose_curve(curves);
76 
77  if(curve_name == "")
78  throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
79  "Could not agree on an ECC curve with the client");
80 
81  const uint16_t named_curve_id = Supported_Elliptic_Curves::name_to_curve_id(curve_name);
82  if(named_curve_id == 0)
83  throw Internal_Error("TLS does not support ECC with " + curve_name);
84 
85  std::vector<uint8_t> ecdh_public_val;
86 
87  if(curve_name == "x25519")
88  {
89 #if defined(BOTAN_HAS_CURVE_25519)
90  std::unique_ptr<Curve25519_PrivateKey> x25519(new Curve25519_PrivateKey(rng));
91  ecdh_public_val = x25519->public_value();
92  m_kex_key.reset(x25519.release());
93 #else
94  throw Internal_Error("Negotiated X25519 somehow, but it is disabled");
95 #endif
96  }
97  else
98  {
99  EC_Group ec_group(curve_name);
100  std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group));
101 
102  // follow client's preference for point compression
103  ecdh_public_val = ecdh->public_value(
104  state.client_hello()->prefers_compressed_ec_points() ?
106 
107  m_kex_key.reset(ecdh.release());
108  }
109 
110  m_params.push_back(3); // named curve
111  m_params.push_back(get_byte(0, named_curve_id));
112  m_params.push_back(get_byte(1, named_curve_id));
113 
114  append_tls_length_value(m_params, ecdh_public_val, 1);
115  }
116 #if defined(BOTAN_HAS_SRP6)
117  else if(kex_algo == "SRP_SHA")
118  {
119  const std::string srp_identifier = state.client_hello()->srp_identifier();
120 
121  std::string group_id;
122  BigInt v;
123  std::vector<uint8_t> salt;
124 
125  const bool found = creds.srp_verifier("tls-server", hostname,
126  srp_identifier,
127  group_id, v, salt,
128  policy.hide_unknown_users());
129 
130  if(!found)
131  throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY,
132  "Unknown SRP user " + srp_identifier);
133 
134  m_srp_params.reset(new SRP6_Server_Session);
135 
136  BigInt B = m_srp_params->step1(v, group_id,
137  "SHA-1", rng);
138 
139  DL_Group group(group_id);
140 
141  append_tls_length_value(m_params, BigInt::encode(group.get_p()), 2);
142  append_tls_length_value(m_params, BigInt::encode(group.get_g()), 2);
143  append_tls_length_value(m_params, salt, 1);
144  append_tls_length_value(m_params, BigInt::encode(B), 2);
145  }
146 #endif
147 #if defined(BOTAN_HAS_CECPQ1)
148  else if(kex_algo == "CECPQ1")
149  {
150  std::vector<uint8_t> cecpq1_offer(CECPQ1_OFFER_BYTES);
151  m_cecpq1_key.reset(new CECPQ1_key);
152  CECPQ1_offer(cecpq1_offer.data(), m_cecpq1_key.get(), rng);
153  append_tls_length_value(m_params, cecpq1_offer, 2);
154  }
155 #endif
156  else if(kex_algo != "PSK")
157  {
158  throw Internal_Error("Server_Key_Exchange: Unknown kex type " + kex_algo);
159  }
160 
161  if(state.ciphersuite().sig_algo() != "")
162  {
163  BOTAN_ASSERT(signing_key, "Signing key was set");
164 
165  std::pair<std::string, Signature_Format> format =
166  state.choose_sig_format(*signing_key, m_hash_algo, m_sig_algo, false, policy);
167 
168  PK_Signer signer(*signing_key, rng, format.first, format.second);
169 
170  signer.update(state.client_hello()->random());
171  signer.update(state.server_hello()->random());
172  signer.update(params());
173  m_signature = signer.signature(rng);
174  }
175 
176  state.hash().update(io.send(*this));
177  }
static uint16_t name_to_curve_id(const std::string &name)
const std::vector< uint8_t > & params() const
Definition: tls_messages.h:586
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
void CECPQ1_offer(uint8_t send[CECPQ1_OFFER_BYTES], CECPQ1_key *offer_key_output, RandomNumberGenerator &rng)
Definition: cecpq1.cpp:14
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:47
static std::vector< uint8_t > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
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
Botan::TLS::Server_Key_Exchange::Server_Key_Exchange ( const std::vector< uint8_t > &  buf,
const std::string &  kex_algo,
const std::string &  sig_algo,
Protocol_Version  version 
)

Deserialize a Server Key Exchange message

Definition at line 182 of file msg_server_kex.cpp.

References Botan::TLS::TLS_Data_Reader::assert_done(), Botan::TLS::TLS_Data_Reader::get_byte(), Botan::TLS::TLS_Data_Reader::get_range(), Botan::TLS::TLS_Data_Reader::get_string(), Botan::TLS::TLS_Data_Reader::get_uint16_t(), Botan::TLS::Signature_Algorithms::hash_algo_name(), Botan::TLS::TLS_Data_Reader::read_so_far(), Botan::TLS::Signature_Algorithms::sig_algo_name(), and Botan::TLS::Protocol_Version::supports_negotiable_signature_algorithms().

186  {
187  TLS_Data_Reader reader("ServerKeyExchange", buf);
188 
189  /*
190  * Here we are deserializing enough to find out what offset the
191  * signature is at. All processing is done when the Client Key Exchange
192  * is prepared.
193  */
194 
195  if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
196  {
197  reader.get_string(2, 0, 65535); // identity hint
198  }
199 
200  if(kex_algo == "DH" || kex_algo == "DHE_PSK")
201  {
202  // 3 bigints, DH p, g, Y
203 
204  for(size_t i = 0; i != 3; ++i)
205  {
206  reader.get_range<uint8_t>(2, 1, 65535);
207  }
208  }
209  else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
210  {
211  reader.get_byte(); // curve type
212  reader.get_uint16_t(); // curve id
213  reader.get_range<uint8_t>(1, 1, 255); // public key
214  }
215  else if(kex_algo == "SRP_SHA")
216  {
217  // 2 bigints (N,g) then salt, then server B
218 
219  reader.get_range<uint8_t>(2, 1, 65535);
220  reader.get_range<uint8_t>(2, 1, 65535);
221  reader.get_range<uint8_t>(1, 1, 255);
222  reader.get_range<uint8_t>(2, 1, 65535);
223  }
224  else if(kex_algo == "CECPQ1")
225  {
226  // u16 blob
227  reader.get_range<uint8_t>(2, 1, 65535);
228  }
229  else if(kex_algo != "PSK")
230  throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo);
231 
232  m_params.assign(buf.data(), buf.data() + reader.read_so_far());
233 
234  if(sig_algo != "")
235  {
236  if(version.supports_negotiable_signature_algorithms())
237  {
238  m_hash_algo = Signature_Algorithms::hash_algo_name(reader.get_byte());
239  m_sig_algo = Signature_Algorithms::sig_algo_name(reader.get_byte());
240  }
241 
242  m_signature = reader.get_range<uint8_t>(2, 0, 65535);
243  }
244 
245  reader.assert_done();
246  }
static std::string sig_algo_name(uint8_t code)
static std::string hash_algo_name(uint8_t code)
Botan::TLS::Server_Key_Exchange::~Server_Key_Exchange ( )
default

Member Function Documentation

const std::vector<uint8_t>& Botan::TLS::Server_Key_Exchange::params ( ) const
inline

Definition at line 586 of file tls_messages.h.

Referenced by Server_Key_Exchange(), and verify().

586 { return m_params; }
const Private_Key & Botan::TLS::Server_Key_Exchange::server_kex_key ( ) const

Definition at line 298 of file msg_server_kex.cpp.

References BOTAN_ASSERT_NONNULL.

299  {
300  BOTAN_ASSERT_NONNULL(m_kex_key);
301  return *m_kex_key;
302  }
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:79
Handshake_Type Botan::TLS::Server_Key_Exchange::type ( ) const
inlineoverridevirtual
Returns
the message type

Implements Botan::TLS::Handshake_Message.

Definition at line 584 of file tls_messages.h.

References Botan::TLS::SERVER_KEX.

584 { return SERVER_KEX; }
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)
bool Botan::TLS::Server_Key_Exchange::verify ( const Public_Key server_key,
const Handshake_State state,
const Policy policy 
) const

Verify a Server Key Exchange message

Definition at line 273 of file msg_server_kex.cpp.

References Botan::TLS::Policy::check_peer_key_acceptable(), Botan::PK_Verifier::check_signature(), Botan::TLS::Handshake_State::client_hello(), params(), Botan::TLS::Handshake_State::parse_sig_format(), Botan::TLS::Handshake_State::server_hello(), and Botan::PK_Verifier::update().

276  {
277  policy.check_peer_key_acceptable(server_key);
278 
279  std::pair<std::string, Signature_Format> format =
280  state.parse_sig_format(server_key, m_hash_algo, m_sig_algo,
281  false, policy);
282 
283  PK_Verifier verifier(server_key, format.first, format.second);
284 
285  verifier.update(state.client_hello()->random());
286  verifier.update(state.server_hello()->random());
287  verifier.update(params());
288 
289  const bool signature_valid = verifier.check_signature(m_signature);
290 
291 #if defined(BOTAN_UNSAFE_FUZZER_MODE)
292  return true;
293 #else
294  return signature_valid;
295 #endif
296  }
const std::vector< uint8_t > & params() const
Definition: tls_messages.h:586

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