Botan  2.7.0
Crypto and TLS for C++11
msg_server_kex.cpp
Go to the documentation of this file.
1 /*
2 * Server Key Exchange Message
3 * (C) 2004-2010,2012,2015,2016 Jack Lloyd
4 * 2017 Harry Reimann, Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/tls_messages.h>
10 #include <botan/tls_extensions.h>
11 #include <botan/internal/tls_reader.h>
12 #include <botan/internal/tls_handshake_io.h>
13 #include <botan/internal/tls_handshake_state.h>
14 #include <botan/credentials_manager.h>
15 #include <botan/loadstor.h>
16 #include <botan/pubkey.h>
17 
18 #include <botan/dh.h>
19 #include <botan/ecdh.h>
20 
21 #if defined(BOTAN_HAS_CURVE_25519)
22  #include <botan/curve25519.h>
23 #endif
24 
25 #if defined(BOTAN_HAS_CECPQ1)
26  #include <botan/cecpq1.h>
27 #endif
28 
29 #if defined(BOTAN_HAS_SRP6)
30  #include <botan/srp6.h>
31 #endif
32 
33 namespace Botan {
34 
35 namespace TLS {
36 
37 /**
38 * Create a new Server Key Exchange message
39 */
41  Handshake_State& state,
42  const Policy& policy,
43  Credentials_Manager& creds,
45  const Private_Key* signing_key)
46  {
47  const std::string hostname = state.client_hello()->sni_hostname();
48  const Kex_Algo kex_algo = state.ciphersuite().kex_method();
49 
50  if(kex_algo == Kex_Algo::PSK || kex_algo == Kex_Algo::DHE_PSK || kex_algo == 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 == Kex_Algo::DH || kex_algo == Kex_Algo::DHE_PSK)
59  {
60  const std::vector<Group_Params> dh_groups = state.client_hello()->supported_dh_groups();
61 
62  Group_Params shared_group = Group_Params::NONE;
63 
64  /*
65  If the client does not send any DH groups in the supported groups
66  extension, but does offer DH ciphersuites, we select a group arbitrarily
67  */
68 
69  if(dh_groups.empty())
70  {
71  shared_group = policy.default_dh_group();
72  }
73  else
74  {
75  shared_group = policy.choose_key_exchange_group(dh_groups);
76  }
77 
78  if(shared_group == Group_Params::NONE)
80  "Could not agree on a DH group with the client");
81 
82  BOTAN_ASSERT(group_param_is_dh(shared_group), "DH groups for the DH ciphersuites god");
83 
84  const std::string group_name = state.callbacks().tls_decode_group_param(shared_group);
85  std::unique_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, DL_Group(group_name)));
86 
87  append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_p()), 2);
88  append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_g()), 2);
89  append_tls_length_value(m_params, dh->public_value(), 2);
90  m_kex_key.reset(dh.release());
91  }
92  else if(kex_algo == Kex_Algo::ECDH || kex_algo == Kex_Algo::ECDHE_PSK)
93  {
94  const std::vector<Group_Params> ec_groups = state.client_hello()->supported_ecc_curves();
95 
96  if(ec_groups.empty())
97  throw Internal_Error("Client sent no ECC extension but we negotiated ECDH");
98 
99  Group_Params shared_group = policy.choose_key_exchange_group(ec_groups);
100 
101  if(shared_group == Group_Params::NONE)
102  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "No shared ECC group with client");
103 
104  std::vector<uint8_t> ecdh_public_val;
105 
106  if(shared_group == Group_Params::X25519)
107  {
108 #if defined(BOTAN_HAS_CURVE_25519)
109  std::unique_ptr<Curve25519_PrivateKey> x25519(new Curve25519_PrivateKey(rng));
110  ecdh_public_val = x25519->public_value();
111  m_kex_key.reset(x25519.release());
112 #else
113  throw Internal_Error("Negotiated X25519 somehow, but it is disabled");
114 #endif
115  }
116  else
117  {
118  Group_Params curve = policy.choose_key_exchange_group(ec_groups);
119 
120  const std::string curve_name = state.callbacks().tls_decode_group_param(curve);
121 
122  EC_Group ec_group(curve_name);
123  std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group));
124 
125  // follow client's preference for point compression
126  ecdh_public_val = ecdh->public_value(
127  state.client_hello()->prefers_compressed_ec_points() ?
129 
130  m_kex_key.reset(ecdh.release());
131  }
132 
133  const uint16_t named_curve_id = static_cast<uint16_t>(shared_group);
134  m_params.push_back(3); // named curve
135  m_params.push_back(get_byte(0, named_curve_id));
136  m_params.push_back(get_byte(1, named_curve_id));
137 
138  append_tls_length_value(m_params, ecdh_public_val, 1);
139  }
140 #if defined(BOTAN_HAS_SRP6)
141  else if(kex_algo == Kex_Algo::SRP_SHA)
142  {
143  const std::string srp_identifier = state.client_hello()->srp_identifier();
144 
145  std::string group_id;
146  BigInt v;
147  std::vector<uint8_t> salt;
148 
149  const bool found = creds.srp_verifier("tls-server", hostname,
150  srp_identifier,
151  group_id, v, salt,
152  policy.hide_unknown_users());
153 
154  if(!found)
156  "Unknown SRP user " + srp_identifier);
157 
158  m_srp_params.reset(new SRP6_Server_Session);
159 
160  BigInt B = m_srp_params->step1(v, group_id,
161  "SHA-1", rng);
162 
163  DL_Group group(group_id);
164 
165  append_tls_length_value(m_params, BigInt::encode(group.get_p()), 2);
166  append_tls_length_value(m_params, BigInt::encode(group.get_g()), 2);
167  append_tls_length_value(m_params, salt, 1);
168  append_tls_length_value(m_params, BigInt::encode(B), 2);
169  }
170 #endif
171 #if defined(BOTAN_HAS_CECPQ1)
172  else if(kex_algo == Kex_Algo::CECPQ1)
173  {
174  std::vector<uint8_t> cecpq1_offer(CECPQ1_OFFER_BYTES);
175  m_cecpq1_key.reset(new CECPQ1_key);
176  CECPQ1_offer(cecpq1_offer.data(), m_cecpq1_key.get(), rng);
177  append_tls_length_value(m_params, cecpq1_offer, 2);
178  }
179 #endif
180  else if(kex_algo != Kex_Algo::PSK)
181  {
182  throw Internal_Error("Server_Key_Exchange: Unknown kex type " +
183  kex_method_to_string(kex_algo));
184  }
185 
186  if(state.ciphersuite().signature_used())
187  {
188  BOTAN_ASSERT(signing_key, "Signing key was set");
189 
190  std::pair<std::string, Signature_Format> format =
191  state.choose_sig_format(*signing_key, m_scheme, false, policy);
192 
193  std::vector<uint8_t> buf = state.client_hello()->random();
194 
195  buf += state.server_hello()->random();
196  buf += params();
197 
198  m_signature =
199  state.callbacks().tls_sign_message(*signing_key, rng,
200  format.first, format.second, buf);
201  }
202 
203  state.hash().update(io.send(*this));
204  }
205 
206 /**
207 * Deserialize a Server Key Exchange message
208 */
209 Server_Key_Exchange::Server_Key_Exchange(const std::vector<uint8_t>& buf,
210  const Kex_Algo kex_algo,
211  const Auth_Method auth_method,
212  Protocol_Version version)
213  {
214  TLS_Data_Reader reader("ServerKeyExchange", buf);
215 
216  /*
217  * Here we are deserializing enough to find out what offset the
218  * signature is at. All processing is done when the Client Key Exchange
219  * is prepared.
220  */
221 
222  if(kex_algo == Kex_Algo::PSK || kex_algo == Kex_Algo::DHE_PSK || kex_algo == Kex_Algo::ECDHE_PSK)
223  {
224  reader.get_string(2, 0, 65535); // identity hint
225  }
226 
227  if(kex_algo == Kex_Algo::DH || kex_algo == Kex_Algo::DHE_PSK)
228  {
229  // 3 bigints, DH p, g, Y
230 
231  for(size_t i = 0; i != 3; ++i)
232  {
233  reader.get_range<uint8_t>(2, 1, 65535);
234  }
235  }
236  else if(kex_algo == Kex_Algo::ECDH || kex_algo == Kex_Algo::ECDHE_PSK)
237  {
238  reader.get_byte(); // curve type
239  reader.get_uint16_t(); // curve id
240  reader.get_range<uint8_t>(1, 1, 255); // public key
241  }
242  else if(kex_algo == Kex_Algo::SRP_SHA)
243  {
244  // 2 bigints (N,g) then salt, then server B
245 
246  reader.get_range<uint8_t>(2, 1, 65535);
247  reader.get_range<uint8_t>(2, 1, 65535);
248  reader.get_range<uint8_t>(1, 1, 255);
249  reader.get_range<uint8_t>(2, 1, 65535);
250  }
251  else if(kex_algo == Kex_Algo::CECPQ1)
252  {
253  // u16 blob
254  reader.get_range<uint8_t>(2, 1, 65535);
255  }
256  else if(kex_algo != Kex_Algo::PSK)
257  throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " +
258  kex_method_to_string(kex_algo));
259 
260  m_params.assign(buf.data(), buf.data() + reader.read_so_far());
261 
262  if(auth_method != Auth_Method::ANONYMOUS && auth_method != Auth_Method::IMPLICIT)
263  {
265  {
266  m_scheme = static_cast<Signature_Scheme>(reader.get_uint16_t());
267  }
268 
269  m_signature = reader.get_range<uint8_t>(2, 0, 65535);
270  }
271 
272  reader.assert_done();
273  }
274 
275 /**
276 * Serialize a Server Key Exchange message
277 */
278 std::vector<uint8_t> Server_Key_Exchange::serialize() const
279  {
280  std::vector<uint8_t> buf = params();
281 
282  if(m_signature.size())
283  {
284  if(m_scheme != Signature_Scheme::NONE)
285  {
286  const uint16_t scheme_code = static_cast<uint16_t>(m_scheme);
287  buf.push_back(get_byte(0, scheme_code));
288  buf.push_back(get_byte(1, scheme_code));
289  }
290 
291  append_tls_length_value(buf, m_signature, 2);
292  }
293 
294  return buf;
295  }
296 
297 /**
298 * Verify a Server Key Exchange message
299 */
301  const Handshake_State& state,
302  const Policy& policy) const
303  {
304  policy.check_peer_key_acceptable(server_key);
305 
306  std::pair<std::string, Signature_Format> format =
307  state.parse_sig_format(server_key, m_scheme, false, policy);
308 
309  std::vector<uint8_t> buf = state.client_hello()->random();
310 
311  buf += state.server_hello()->random();
312  buf += params();
313 
314  const bool signature_valid =
315  state.callbacks().tls_verify_message(server_key, format.first, format.second,
316  buf, m_signature);
317 
318 #if defined(BOTAN_UNSAFE_FUZZER_MODE)
319  return true;
320 #else
321  return signature_valid;
322 #endif
323  }
324 
326  {
327  BOTAN_ASSERT_NONNULL(m_kex_key);
328  return *m_kex_key;
329  }
330 
331 }
332 
333 }
Server_Key_Exchange(Handshake_IO &io, Handshake_State &state, const Policy &policy, Credentials_Manager &creds, RandomNumberGenerator &rng, const Private_Key *signing_key=nullptr)
virtual std::string tls_decode_group_param(Group_Params group_param)
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
void server_hello(Server_Hello *server_hello)
const std::vector< uint8_t > & params() const
Definition: tls_messages.h:518
bool group_param_is_dh(Group_Params group)
Definition: tls_algos.cpp:118
size_t read_so_far() const
Definition: tls_reader.h:36
std::pair< std::string, Signature_Format > parse_sig_format(const Public_Key &key, Signature_Scheme scheme, bool for_client_auth, const Policy &policy) const
virtual bool tls_verify_message(const Public_Key &key, const std::string &emsa, Signature_Format format, const std::vector< uint8_t > &msg, const std::vector< uint8_t > &sig)
virtual void check_peer_key_acceptable(const Public_Key &public_key) const
Definition: tls_policy.cpp:229
Signature_Scheme
Definition: tls_algos.h:84
std::pair< std::string, Signature_Format > choose_sig_format(const Private_Key &key, Signature_Scheme &scheme, bool for_client_auth, const Policy &policy) const
virtual std::string psk_identity_hint(const std::string &type, const std::string &context)
const BigInt & get_g() const
Definition: dl_group.cpp:417
std::string kex_method_to_string(Kex_Algo method)
Definition: tls_algos.cpp:29
virtual Group_Params choose_key_exchange_group(const std::vector< Group_Params > &peer_groups) const
Definition: tls_policy.cpp:130
Kex_Algo kex_method() const
virtual Group_Params default_dh_group() const
Definition: tls_policy.cpp:146
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
const Ciphersuite & ciphersuite() const
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:43
std::string get_string(size_t len_bytes, size_t min_bytes, size_t max_bytes)
Definition: tls_reader.h:115
const BigInt & get_p() const
Definition: dl_group.cpp:409
virtual std::vector< uint8_t > tls_sign_message(const Private_Key &key, RandomNumberGenerator &rng, const std::string &emsa, Signature_Format format, const std::vector< uint8_t > &msg)
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:95
void client_hello(Client_Hello *client_hello)
std::vector< T > get_range(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:94
void update(const uint8_t in[], size_t length)
virtual bool srp_verifier(const std::string &type, const std::string &context, const std::string &identifier, std::string &group_name, BigInt &verifier, std::vector< uint8_t > &salt, bool generate_fake_on_unknown)
Definition: alg_id.cpp:13
const Private_Key & server_kex_key() const
bool verify(const Public_Key &server_key, const Handshake_State &state, const Policy &policy) const
void CECPQ1_offer(uint8_t send[CECPQ1_OFFER_BYTES], CECPQ1_key *offer_key_output, RandomNumberGenerator &rng)
Definition: cecpq1.cpp:15
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
virtual bool hide_unknown_users() const
Definition: tls_policy.cpp:328
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