Botan  2.1.0
Crypto and TLS for C++11
msg_client_kex.cpp
Go to the documentation of this file.
1 /*
2 * Client Key Exchange Message
3 * (C) 2004-2010,2016 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/tls_messages.h>
9 #include <botan/tls_extensions.h>
10 #include <botan/internal/tls_reader.h>
11 #include <botan/internal/tls_handshake_io.h>
12 #include <botan/internal/tls_handshake_state.h>
13 #include <botan/internal/tls_handshake_hash.h>
14 #include <botan/credentials_manager.h>
15 #include <botan/rng.h>
16 #include <botan/loadstor.h>
17 #include <botan/internal/ct_utils.h>
18 
19 #include <botan/pubkey.h>
20 
21 #include <botan/dh.h>
22 #include <botan/ecdh.h>
23 #include <botan/rsa.h>
24 
25 #if defined(BOTAN_HAS_CURVE_25519)
26  #include <botan/curve25519.h>
27 #endif
28 
29 #if defined(BOTAN_HAS_CECPQ1)
30  #include <botan/cecpq1.h>
31 #endif
32 
33 #if defined(BOTAN_HAS_SRP6)
34  #include <botan/srp6.h>
35 #endif
36 
37 namespace Botan {
38 
39 namespace TLS {
40 
41 /*
42 * Create a new Client Key Exchange message
43 */
45  Handshake_State& state,
46  const Policy& policy,
47  Credentials_Manager& creds,
49  const std::string& hostname,
51  {
52  const std::string kex_algo = state.ciphersuite().kex_algo();
53 
54  if(kex_algo == "PSK")
55  {
56  std::string identity_hint = "";
57 
58  if(state.server_kex())
59  {
60  TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
61  identity_hint = reader.get_string(2, 0, 65535);
62  }
63 
64  const std::string psk_identity =
65  creds.psk_identity("tls-client", hostname, identity_hint);
66 
67  append_tls_length_value(m_key_material, psk_identity, 2);
68 
69  SymmetricKey psk = creds.psk("tls-client", hostname, psk_identity);
70 
71  std::vector<uint8_t> zeros(psk.length());
72 
73  append_tls_length_value(m_pre_master, zeros, 2);
74  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
75  }
76  else if(state.server_kex())
77  {
78  TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
79 
80  SymmetricKey psk;
81 
82  if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
83  {
84  std::string identity_hint = reader.get_string(2, 0, 65535);
85 
86  const std::string psk_identity =
87  creds.psk_identity("tls-client", hostname, identity_hint);
88 
89  append_tls_length_value(m_key_material, psk_identity, 2);
90 
91  psk = creds.psk("tls-client", hostname, psk_identity);
92  }
93 
94  if(kex_algo == "DH" || kex_algo == "DHE_PSK")
95  {
96  BigInt p = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
97  BigInt g = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
98  BigInt Y = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
99 
100  if(reader.remaining_bytes())
101  throw Decoding_Error("Bad params size for DH key exchange");
102 
103  /*
104  * A basic check for key validity. As we do not know q here we
105  * cannot check that Y is in the right subgroup. However since
106  * our key is ephemeral there does not seem to be any
107  * advantage to bogus keys anyway.
108  */
109  if(Y <= 1 || Y >= p - 1)
111  "Server sent bad DH key for DHE exchange");
112 
113  DL_Group group(p, g);
114 
115  if(!group.verify_group(rng, false))
117  "DH group validation failed");
118 
119  DH_PublicKey counterparty_key(group, Y);
120 
121  policy.check_peer_key_acceptable(counterparty_key);
122 
123  DH_PrivateKey priv_key(rng, group);
124 
125  PK_Key_Agreement ka(priv_key, rng, "Raw");
126 
128  ka.derive_key(0, counterparty_key.public_value()).bits_of());
129 
130  if(kex_algo == "DH")
131  m_pre_master = dh_secret;
132  else
133  {
134  append_tls_length_value(m_pre_master, dh_secret, 2);
135  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
136  }
137 
138  append_tls_length_value(m_key_material, priv_key.public_value(), 2);
139  }
140  else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
141  {
142  const uint8_t curve_type = reader.get_byte();
143 
144  if(curve_type != 3)
145  throw Decoding_Error("Server sent non-named ECC curve");
146 
147  const uint16_t curve_id = reader.get_uint16_t();
148 
149  const std::string curve_name = Supported_Elliptic_Curves::curve_id_to_name(curve_id);
150 
151  if(curve_name == "")
152  throw Decoding_Error("Server sent unknown named curve " + std::to_string(curve_id));
153 
154  if(!policy.allowed_ecc_curve(curve_name))
155  {
157  "Server sent ECC curve prohibited by policy");
158  }
159 
160  const std::vector<uint8_t> ecdh_key = reader.get_range<uint8_t>(1, 1, 255);
161  std::vector<uint8_t> our_ecdh_public;
162  secure_vector<uint8_t> ecdh_secret;
163 
164  if(curve_name == "x25519")
165  {
166 #if defined(BOTAN_HAS_CURVE_25519)
167  if(ecdh_key.size() != 32)
168  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Invalid X25519 key size");
169 
170  Curve25519_PublicKey counterparty_key(ecdh_key);
171  policy.check_peer_key_acceptable(counterparty_key);
172  Curve25519_PrivateKey priv_key(rng);
173  PK_Key_Agreement ka(priv_key, rng, "Raw");
174  ecdh_secret = ka.derive_key(0, counterparty_key.public_value()).bits_of();
175 
176  // X25519 is always compressed but sent as "uncompressed" in TLS
177  our_ecdh_public = priv_key.public_value();
178 #else
179  throw Internal_Error("Negotiated X25519 somehow, but it is disabled");
180 #endif
181  }
182  else
183  {
184  EC_Group group(curve_name);
185  ECDH_PublicKey counterparty_key(group, OS2ECP(ecdh_key, group.get_curve()));
186  policy.check_peer_key_acceptable(counterparty_key);
187  ECDH_PrivateKey priv_key(rng, group);
188  PK_Key_Agreement ka(priv_key, rng, "Raw");
189  ecdh_secret = ka.derive_key(0, counterparty_key.public_value()).bits_of();
190 
191  // follow server's preference for point compression
192  our_ecdh_public = priv_key.public_value(
193  state.server_hello()->prefers_compressed_ec_points() ? PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED);
194  }
195 
196  if(kex_algo == "ECDH")
197  m_pre_master = ecdh_secret;
198  else
199  {
200  append_tls_length_value(m_pre_master, ecdh_secret, 2);
201  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
202  }
203 
204  append_tls_length_value(m_key_material, our_ecdh_public, 1);
205  }
206 #if defined(BOTAN_HAS_SRP6)
207  else if(kex_algo == "SRP_SHA")
208  {
209  const BigInt N = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
210  const BigInt g = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
211  std::vector<uint8_t> salt = reader.get_range<uint8_t>(1, 1, 255);
212  const BigInt B = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
213 
214  const std::string srp_group = srp6_group_identifier(N, g);
215 
216  const std::string srp_identifier =
217  creds.srp_identifier("tls-client", hostname);
218 
219  const std::string srp_password =
220  creds.srp_password("tls-client", hostname, srp_identifier);
221 
222  std::pair<BigInt, SymmetricKey> srp_vals =
223  srp6_client_agree(srp_identifier,
224  srp_password,
225  srp_group,
226  "SHA-1",
227  salt,
228  B,
229  rng);
230 
231  append_tls_length_value(m_key_material, BigInt::encode(srp_vals.first), 2);
232  m_pre_master = srp_vals.second.bits_of();
233  }
234 #endif
235 
236 #if defined(BOTAN_HAS_CECPQ1)
237  else if(kex_algo == "CECPQ1")
238  {
239  const std::vector<uint8_t> cecpq1_offer = reader.get_range<uint8_t>(2, 1, 65535);
240 
241  if(cecpq1_offer.size() != CECPQ1_OFFER_BYTES)
242  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Invalid CECPQ1 key size");
243 
244  std::vector<uint8_t> newhope_accept(CECPQ1_ACCEPT_BYTES);
246  CECPQ1_accept(shared_secret.data(), newhope_accept.data(), cecpq1_offer.data(), rng);
247  append_tls_length_value(m_key_material, newhope_accept, 2);
248  m_pre_master = shared_secret;
249  }
250 #endif
251  else
252  {
253  throw Internal_Error("Client_Key_Exchange: Unknown kex " + kex_algo);
254  }
255 
256  reader.assert_done();
257  }
258  else
259  {
260  // No server key exchange msg better mean RSA kex + RSA key in cert
261 
262  if(kex_algo != "RSA")
263  throw Unexpected_Message("No server kex but negotiated kex " + kex_algo);
264 
265  if(!server_public_key)
266  throw Internal_Error("No server public key for RSA exchange");
267 
268  if(auto rsa_pub = dynamic_cast<const RSA_PublicKey*>(server_public_key))
269  {
270  const Protocol_Version offered_version = state.client_hello()->version();
271 
272  m_pre_master = rng.random_vec(48);
273  m_pre_master[0] = offered_version.major_version();
274  m_pre_master[1] = offered_version.minor_version();
275 
276  PK_Encryptor_EME encryptor(*rsa_pub, rng, "PKCS1v15");
277 
278  const std::vector<uint8_t> encrypted_key = encryptor.encrypt(m_pre_master, rng);
279 
280  append_tls_length_value(m_key_material, encrypted_key, 2);
281  }
282  else
284  "Expected a RSA key in server cert but got " +
285  server_public_key->algo_name());
286  }
287 
288  state.hash().update(io.send(*this));
289  }
290 
291 /*
292 * Read a Client Key Exchange message
293 */
294 Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents,
295  const Handshake_State& state,
296  const Private_Key* server_rsa_kex_key,
297  Credentials_Manager& creds,
298  const Policy& policy,
300  {
301  const std::string kex_algo = state.ciphersuite().kex_algo();
302 
303  if(kex_algo == "RSA")
304  {
305  BOTAN_ASSERT(state.server_certs() && !state.server_certs()->cert_chain().empty(),
306  "RSA key exchange negotiated so server sent a certificate");
307 
308  if(!server_rsa_kex_key)
309  throw Internal_Error("Expected RSA kex but no server kex key set");
310 
311  if(!dynamic_cast<const RSA_PrivateKey*>(server_rsa_kex_key))
312  throw Internal_Error("Expected RSA key but got " + server_rsa_kex_key->algo_name());
313 
314  TLS_Data_Reader reader("ClientKeyExchange", contents);
315  const std::vector<uint8_t> encrypted_pre_master = reader.get_range<uint8_t>(2, 0, 65535);
316 
317  PK_Decryptor_EME decryptor(*server_rsa_kex_key, rng, "PKCS1v15");
318 
319  const uint8_t client_major = state.client_hello()->version().major_version();
320  const uint8_t client_minor = state.client_hello()->version().minor_version();
321 
322  /*
323  * PK_Decryptor::decrypt_or_random will return a random value if
324  * either the length does not match the expected value or if the
325  * version number embedded in the PMS does not match the one sent
326  * in the client hello.
327  */
328  const size_t expected_plaintext_size = 48;
329  const size_t expected_content_size = 2;
330  const uint8_t expected_content_bytes[expected_content_size] = { client_major, client_minor };
331  const uint8_t expected_content_pos[expected_content_size] = { 0, 1 };
332 
333  m_pre_master =
334  decryptor.decrypt_or_random(encrypted_pre_master.data(),
335  encrypted_pre_master.size(),
336  expected_plaintext_size,
337  rng,
338  expected_content_bytes,
339  expected_content_pos,
340  expected_content_size);
341  }
342  else
343  {
344  TLS_Data_Reader reader("ClientKeyExchange", contents);
345 
346  SymmetricKey psk;
347 
348  if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
349  {
350  const std::string psk_identity = reader.get_string(2, 0, 65535);
351 
352  psk = creds.psk("tls-server",
353  state.client_hello()->sni_hostname(),
354  psk_identity);
355 
356  if(psk.length() == 0)
357  {
358  if(policy.hide_unknown_users())
359  psk = SymmetricKey(rng, 16);
360  else
362  "No PSK for identifier " + psk_identity);
363  }
364  }
365 
366  if(kex_algo == "PSK")
367  {
368  std::vector<uint8_t> zeros(psk.length());
369  append_tls_length_value(m_pre_master, zeros, 2);
370  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
371  }
372 #if defined(BOTAN_HAS_SRP6)
373  else if(kex_algo == "SRP_SHA")
374  {
375  SRP6_Server_Session& srp = state.server_kex()->server_srp_params();
376 
377  m_pre_master = srp.step2(BigInt::decode(reader.get_range<uint8_t>(2, 0, 65535))).bits_of();
378  }
379 #endif
380 #if defined(BOTAN_HAS_CECPQ1)
381  else if(kex_algo == "CECPQ1")
382  {
383  const CECPQ1_key& cecpq1_offer = state.server_kex()->cecpq1_key();
384 
385  const std::vector<uint8_t> cecpq1_accept = reader.get_range<uint8_t>(2, 0, 65535);
386  if(cecpq1_accept.size() != CECPQ1_ACCEPT_BYTES)
387  throw Decoding_Error("Invalid size for CECPQ1 accept message");
388 
389  m_pre_master.resize(CECPQ1_SHARED_KEY_BYTES);
390  CECPQ1_finish(m_pre_master.data(), cecpq1_offer, cecpq1_accept.data());
391  }
392 #endif
393  else if(kex_algo == "DH" || kex_algo == "DHE_PSK" ||
394  kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
395  {
396  const Private_Key& private_key = state.server_kex()->server_kex_key();
397 
398  const PK_Key_Agreement_Key* ka_key =
399  dynamic_cast<const PK_Key_Agreement_Key*>(&private_key);
400 
401  if(!ka_key)
402  throw Internal_Error("Expected key agreement key type but got " +
403  private_key.algo_name());
404 
405  try
406  {
407  PK_Key_Agreement ka(*ka_key, rng, "Raw");
408 
409  std::vector<uint8_t> client_pubkey;
410 
411  if(ka_key->algo_name() == "DH")
412  client_pubkey = reader.get_range<uint8_t>(2, 0, 65535);
413  else
414  client_pubkey = reader.get_range<uint8_t>(1, 0, 255);
415 
416  secure_vector<uint8_t> shared_secret = ka.derive_key(0, client_pubkey).bits_of();
417 
418  if(ka_key->algo_name() == "DH")
419  shared_secret = CT::strip_leading_zeros(shared_secret);
420 
421  if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
422  {
423  append_tls_length_value(m_pre_master, shared_secret, 2);
424  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
425  }
426  else
427  m_pre_master = shared_secret;
428  }
429  catch(std::exception &)
430  {
431  /*
432  * Something failed in the DH computation. To avoid possible
433  * timing attacks, randomize the pre-master output and carry
434  * on, allowing the protocol to fail later in the finished
435  * checks.
436  */
437  m_pre_master = rng.random_vec(ka_key->public_value().size());
438  }
439  }
440  else
441  throw Internal_Error("Client_Key_Exchange: Unknown kex type " + kex_algo);
442  }
443  }
444 
445 }
446 
447 }
secure_vector< uint8_t > bits_of() const
Definition: symkey.h:31
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
uint8_t minor_version() const
Definition: tls_version.h:82
void CECPQ1_finish(uint8_t shared_key[CECPQ1_SHARED_KEY_BYTES], const CECPQ1_key &offer_key, const uint8_t received[CECPQ1_ACCEPT_BYTES])
Definition: cecpq1.cpp:40
void server_hello(Server_Hello *server_hello)
std::vector< uint8_t > public_value() const
Definition: ecdh.h:50
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:133
virtual std::string srp_identifier(const std::string &type, const std::string &context)
virtual std::string srp_password(const std::string &type, const std::string &context, const std::string &identifier)
SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, const uint8_t params[], size_t params_len) const
Definition: pubkey.cpp:202
void server_kex(Server_Key_Exchange *server_kex)
bool verify_group(RandomNumberGenerator &rng, bool strong) const
Definition: dl_group.cpp:161
virtual std::string algo_name() const =0
virtual std::vector< uint8_t > public_value() const =0
std::vector< uint8_t > public_value() const
Definition: curve25519.h:30
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
size_t length() const
Definition: symkey.h:25
virtual bool hide_unknown_users() const
Definition: tls_policy.cpp:277
SymmetricKey step2(const BigInt &A)
Definition: srp6.cpp:144
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
static std::string curve_id_to_name(uint16_t id)
std::string get_string(size_t len_bytes, size_t min_bytes, size_t max_bytes)
Definition: tls_reader.h:115
const CurveGFp & get_curve() const
Definition: ec_group.h:89
std::vector< uint8_t > encrypt(const uint8_t in[], size_t length, RandomNumberGenerator &rng) const
Definition: pubkey.h:46
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
bool allowed_ecc_curve(const std::string &curve) const
Definition: tls_policy.cpp:111
std::vector< uint8_t > public_value() const override
Definition: ecdh.h:92
void client_hello(Client_Hello *client_hello)
std::string kex_algo() const
virtual std::string psk_identity(const std::string &type, const std::string &context, const std::string &identity_hint)
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)
uint8_t major_version() const
Definition: tls_version.h:77
PointGFp OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
Definition: point_gfp.cpp:544
void CECPQ1_accept(uint8_t shared_key[CECPQ1_SHARED_KEY_BYTES], uint8_t send[CECPQ1_ACCEPT_BYTES], const uint8_t received[CECPQ1_OFFER_BYTES], RandomNumberGenerator &rng)
Definition: cecpq1.cpp:25
Definition: alg_id.cpp:13
Client_Key_Exchange(Handshake_IO &io, Handshake_State &state, const Policy &policy, Credentials_Manager &creds, const Public_Key *server_public_key, const std::string &hostname, RandomNumberGenerator &rng)
OctetString SymmetricKey
Definition: symkey.h:136
virtual SymmetricKey psk(const std::string &type, const std::string &context, const std::string &identity)
std::pair< BigInt, SymmetricKey > srp6_client_agree(const std::string &identifier, const std::string &password, const std::string &group_id, const std::string &hash_id, const std::vector< uint8_t > &salt, const BigInt &B, RandomNumberGenerator &rng)
Definition: srp6.cpp:76
std::unique_ptr< Public_Key > server_public_key
Definition: tls_client.cpp:40
std::vector< uint8_t > public_value() const
Definition: dh.cpp:28
void server_certs(Certificate *server_certs)
std::vector< uint8_t > public_value() const override
Definition: curve25519.h:83
virtual void check_peer_key_acceptable(const Public_Key &public_key) const
Definition: tls_policy.cpp:186
const Ciphersuite & ciphersuite() const
static std::vector< uint8_t > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
std::vector< uint8_t > public_value() const override
Definition: dh.cpp:72
std::string srp6_group_identifier(const BigInt &N, const BigInt &g)
Definition: srp6.cpp:52
static BigInt decode(const uint8_t buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:114
secure_vector< uint8_t > strip_leading_zeros(const uint8_t in[], size_t length)
Definition: ct_utils.h:186
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