Botan  2.4.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 * 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/rng.h>
12 
13 #include <botan/internal/tls_reader.h>
14 #include <botan/internal/tls_handshake_io.h>
15 #include <botan/internal/tls_handshake_state.h>
16 #include <botan/internal/tls_handshake_hash.h>
17 #include <botan/credentials_manager.h>
18 #include <botan/internal/ct_utils.h>
19 
20 #include <botan/rsa.h>
21 
22 #if defined(BOTAN_HAS_CECPQ1)
23  #include <botan/cecpq1.h>
24 #endif
25 
26 #if defined(BOTAN_HAS_SRP6)
27  #include <botan/srp6.h>
28 #endif
29 
30 namespace Botan {
31 
32 namespace TLS {
33 
34 /*
35 * Create a new Client Key Exchange message
36 */
38  Handshake_State& state,
39  const Policy& policy,
40  Credentials_Manager& creds,
42  const std::string& hostname,
44  {
45  const std::string kex_algo = state.ciphersuite().kex_algo();
46 
47  if(kex_algo == "PSK")
48  {
49  std::string identity_hint = "";
50 
51  if(state.server_kex())
52  {
53  TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
54  identity_hint = reader.get_string(2, 0, 65535);
55  }
56 
57  const std::string psk_identity =
58  creds.psk_identity("tls-client", hostname, identity_hint);
59 
60  append_tls_length_value(m_key_material, psk_identity, 2);
61 
62  SymmetricKey psk = creds.psk("tls-client", hostname, psk_identity);
63 
64  std::vector<uint8_t> zeros(psk.length());
65 
66  append_tls_length_value(m_pre_master, zeros, 2);
67  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
68  }
69  else if(state.server_kex())
70  {
71  TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
72 
73  SymmetricKey psk;
74 
75  if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
76  {
77  std::string identity_hint = reader.get_string(2, 0, 65535);
78 
79  const std::string psk_identity =
80  creds.psk_identity("tls-client", hostname, identity_hint);
81 
82  append_tls_length_value(m_key_material, psk_identity, 2);
83 
84  psk = creds.psk("tls-client", hostname, psk_identity);
85  }
86 
87  if(kex_algo == "DH" || kex_algo == "DHE_PSK")
88  {
89  const std::vector<uint8_t> modulus = reader.get_range<uint8_t>(2, 1, 65535);
90  const std::vector<uint8_t> generator = reader.get_range<uint8_t>(2, 1, 65535);
91  const std::vector<uint8_t> peer_public_value = reader.get_range<uint8_t>(2, 1, 65535);
92 
93  if(reader.remaining_bytes())
94  throw Decoding_Error("Bad params size for DH key exchange");
95 
96  const std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> dh_result =
97  state.callbacks().tls_dh_agree(modulus, generator, peer_public_value, policy, rng);
98 
99  if(kex_algo == "DH")
100  m_pre_master = dh_result.first;
101  else
102  {
103  append_tls_length_value(m_pre_master, dh_result.first, 2);
104  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
105  }
106 
107  append_tls_length_value(m_key_material, dh_result.second, 2);
108  }
109  else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
110  {
111  const uint8_t curve_type = reader.get_byte();
112 
113  if(curve_type != 3)
114  throw Decoding_Error("Server sent non-named ECC curve");
115 
116  const uint16_t curve_id = reader.get_uint16_t();
117 
118  const std::string curve_name = Supported_Elliptic_Curves::curve_id_to_name(curve_id);
119 
120  if(curve_name == "")
121  throw Decoding_Error("Server sent unknown named curve " + std::to_string(curve_id));
122 
123  if(!policy.allowed_ecc_curve(curve_name))
124  {
126  "Server sent ECC curve prohibited by policy");
127  }
128 
129  const std::vector<uint8_t> peer_public_value = reader.get_range<uint8_t>(1, 1, 255);
130  const std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> ecdh_result =
131  state.callbacks().tls_ecdh_agree(curve_name, peer_public_value, policy, rng,
132  state.server_hello()->prefers_compressed_ec_points());
133 
134  if(kex_algo == "ECDH")
135  m_pre_master = ecdh_result.first;
136  else
137  {
138  append_tls_length_value(m_pre_master, ecdh_result.first, 2);
139  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
140  }
141 
142  append_tls_length_value(m_key_material, ecdh_result.second, 1);
143  }
144 #if defined(BOTAN_HAS_SRP6)
145  else if(kex_algo == "SRP_SHA")
146  {
147  const BigInt N = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
148  const BigInt g = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
149  std::vector<uint8_t> salt = reader.get_range<uint8_t>(1, 1, 255);
150  const BigInt B = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
151 
152  const std::string srp_group = srp6_group_identifier(N, g);
153 
154  const std::string srp_identifier =
155  creds.srp_identifier("tls-client", hostname);
156 
157  const std::string srp_password =
158  creds.srp_password("tls-client", hostname, srp_identifier);
159 
160  std::pair<BigInt, SymmetricKey> srp_vals =
161  srp6_client_agree(srp_identifier,
162  srp_password,
163  srp_group,
164  "SHA-1",
165  salt,
166  B,
167  rng);
168 
169  append_tls_length_value(m_key_material, BigInt::encode(srp_vals.first), 2);
170  m_pre_master = srp_vals.second.bits_of();
171  }
172 #endif
173 
174 #if defined(BOTAN_HAS_CECPQ1)
175  else if(kex_algo == "CECPQ1")
176  {
177  const std::vector<uint8_t> cecpq1_offer = reader.get_range<uint8_t>(2, 1, 65535);
178 
179  if(cecpq1_offer.size() != CECPQ1_OFFER_BYTES)
180  throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Invalid CECPQ1 key size");
181 
182  std::vector<uint8_t> newhope_accept(CECPQ1_ACCEPT_BYTES);
184  CECPQ1_accept(shared_secret.data(), newhope_accept.data(), cecpq1_offer.data(), rng);
185  append_tls_length_value(m_key_material, newhope_accept, 2);
186  m_pre_master = shared_secret;
187  }
188 #endif
189  else
190  {
191  throw Internal_Error("Client_Key_Exchange: Unknown kex " + kex_algo);
192  }
193 
194  reader.assert_done();
195  }
196  else
197  {
198  // No server key exchange msg better mean RSA kex + RSA key in cert
199 
200  if(kex_algo != "RSA")
201  throw Unexpected_Message("No server kex but negotiated kex " + kex_algo);
202 
203  if(!server_public_key)
204  throw Internal_Error("No server public key for RSA exchange");
205 
206  if(auto rsa_pub = dynamic_cast<const RSA_PublicKey*>(server_public_key))
207  {
208  const Protocol_Version offered_version = state.client_hello()->version();
209 
210  m_pre_master = rng.random_vec(48);
211  m_pre_master[0] = offered_version.major_version();
212  m_pre_master[1] = offered_version.minor_version();
213 
214  PK_Encryptor_EME encryptor(*rsa_pub, rng, "PKCS1v15");
215 
216  const std::vector<uint8_t> encrypted_key = encryptor.encrypt(m_pre_master, rng);
217 
218  append_tls_length_value(m_key_material, encrypted_key, 2);
219  }
220  else
222  "Expected a RSA key in server cert but got " +
223  server_public_key->algo_name());
224  }
225 
226  state.hash().update(io.send(*this));
227  }
228 
229 /*
230 * Read a Client Key Exchange message
231 */
232 Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents,
233  const Handshake_State& state,
234  const Private_Key* server_rsa_kex_key,
235  Credentials_Manager& creds,
236  const Policy& policy,
238  {
239  const std::string kex_algo = state.ciphersuite().kex_algo();
240 
241  if(kex_algo == "RSA")
242  {
243  BOTAN_ASSERT(state.server_certs() && !state.server_certs()->cert_chain().empty(),
244  "RSA key exchange negotiated so server sent a certificate");
245 
246  if(!server_rsa_kex_key)
247  throw Internal_Error("Expected RSA kex but no server kex key set");
248 
249  if(!dynamic_cast<const RSA_PrivateKey*>(server_rsa_kex_key))
250  throw Internal_Error("Expected RSA key but got " + server_rsa_kex_key->algo_name());
251 
252  TLS_Data_Reader reader("ClientKeyExchange", contents);
253  const std::vector<uint8_t> encrypted_pre_master = reader.get_range<uint8_t>(2, 0, 65535);
254 
255  PK_Decryptor_EME decryptor(*server_rsa_kex_key, rng, "PKCS1v15");
256 
257  const uint8_t client_major = state.client_hello()->version().major_version();
258  const uint8_t client_minor = state.client_hello()->version().minor_version();
259 
260  /*
261  * PK_Decryptor::decrypt_or_random will return a random value if
262  * either the length does not match the expected value or if the
263  * version number embedded in the PMS does not match the one sent
264  * in the client hello.
265  */
266  const size_t expected_plaintext_size = 48;
267  const size_t expected_content_size = 2;
268  const uint8_t expected_content_bytes[expected_content_size] = { client_major, client_minor };
269  const uint8_t expected_content_pos[expected_content_size] = { 0, 1 };
270 
271  m_pre_master =
272  decryptor.decrypt_or_random(encrypted_pre_master.data(),
273  encrypted_pre_master.size(),
274  expected_plaintext_size,
275  rng,
276  expected_content_bytes,
277  expected_content_pos,
278  expected_content_size);
279  }
280  else
281  {
282  TLS_Data_Reader reader("ClientKeyExchange", contents);
283 
284  SymmetricKey psk;
285 
286  if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
287  {
288  const std::string psk_identity = reader.get_string(2, 0, 65535);
289 
290  psk = creds.psk("tls-server",
291  state.client_hello()->sni_hostname(),
292  psk_identity);
293 
294  if(psk.length() == 0)
295  {
296  if(policy.hide_unknown_users())
297  psk = SymmetricKey(rng, 16);
298  else
300  "No PSK for identifier " + psk_identity);
301  }
302  }
303 
304  if(kex_algo == "PSK")
305  {
306  std::vector<uint8_t> zeros(psk.length());
307  append_tls_length_value(m_pre_master, zeros, 2);
308  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
309  }
310 #if defined(BOTAN_HAS_SRP6)
311  else if(kex_algo == "SRP_SHA")
312  {
313  SRP6_Server_Session& srp = state.server_kex()->server_srp_params();
314 
315  m_pre_master = srp.step2(BigInt::decode(reader.get_range<uint8_t>(2, 0, 65535))).bits_of();
316  }
317 #endif
318 #if defined(BOTAN_HAS_CECPQ1)
319  else if(kex_algo == "CECPQ1")
320  {
321  const CECPQ1_key& cecpq1_offer = state.server_kex()->cecpq1_key();
322 
323  const std::vector<uint8_t> cecpq1_accept = reader.get_range<uint8_t>(2, 0, 65535);
324  if(cecpq1_accept.size() != CECPQ1_ACCEPT_BYTES)
325  throw Decoding_Error("Invalid size for CECPQ1 accept message");
326 
327  m_pre_master.resize(CECPQ1_SHARED_KEY_BYTES);
328  CECPQ1_finish(m_pre_master.data(), cecpq1_offer, cecpq1_accept.data());
329  }
330 #endif
331  else if(kex_algo == "DH" || kex_algo == "DHE_PSK" ||
332  kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
333  {
334  const Private_Key& private_key = state.server_kex()->server_kex_key();
335 
336  const PK_Key_Agreement_Key* ka_key =
337  dynamic_cast<const PK_Key_Agreement_Key*>(&private_key);
338 
339  if(!ka_key)
340  throw Internal_Error("Expected key agreement key type but got " +
341  private_key.algo_name());
342 
343  std::vector<uint8_t> client_pubkey;
344 
345  if(ka_key->algo_name() == "DH")
346  {
347  client_pubkey = reader.get_range<uint8_t>(2, 0, 65535);
348  }
349  else
350  {
351  client_pubkey = reader.get_range<uint8_t>(1, 1, 255);
352  }
353 
354  try
355  {
356  PK_Key_Agreement ka(*ka_key, rng, "Raw");
357 
358  secure_vector<uint8_t> shared_secret = ka.derive_key(0, client_pubkey).bits_of();
359 
360  if(ka_key->algo_name() == "DH")
361  shared_secret = CT::strip_leading_zeros(shared_secret);
362 
363  if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
364  {
365  append_tls_length_value(m_pre_master, shared_secret, 2);
366  append_tls_length_value(m_pre_master, psk.bits_of(), 2);
367  }
368  else
369  m_pre_master = shared_secret;
370  }
371  catch(std::exception &)
372  {
373  /*
374  * Something failed in the DH computation. To avoid possible
375  * timing attacks, randomize the pre-master output and carry
376  * on, allowing the protocol to fail later in the finished
377  * checks.
378  */
379  m_pre_master = rng.random_vec(ka_key->public_value().size());
380  }
381  }
382  else
383  throw Internal_Error("Client_Key_Exchange: Unknown kex type " + kex_algo);
384  }
385  }
386 
387 }
388 
389 }
std::vector< uint8_t > encrypt(const uint8_t in[], size_t length, RandomNumberGenerator &rng) const
Definition: pubkey.h:44
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
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:41
void server_hello(Server_Hello *server_hello)
virtual std::pair< secure_vector< uint8_t >, std::vector< uint8_t > > tls_dh_agree(const std::vector< uint8_t > &modulus, const std::vector< uint8_t > &generator, const std::vector< uint8_t > &peer_public_value, const Policy &policy, RandomNumberGenerator &rng)
virtual std::pair< secure_vector< uint8_t >, std::vector< uint8_t > > tls_ecdh_agree(const std::string &curve_name, const std::vector< uint8_t > &peer_public_value, const Policy &policy, RandomNumberGenerator &rng, bool compressed)
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:132
static std::string curve_id_to_name(uint16_t id)
uint8_t minor_version() const
Definition: tls_version.h:82
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)
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:77
std::string kex_algo() const
void server_kex(Server_Key_Exchange *server_kex)
virtual std::string algo_name() const =0
virtual std::vector< uint8_t > public_value() const =0
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:108
bool allowed_ecc_curve(const std::string &curve) const
Definition: tls_policy.cpp:122
SymmetricKey step2(const BigInt &A)
Definition: srp6.cpp:145
const Ciphersuite & ciphersuite() const
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:29
std::string get_string(size_t len_bytes, size_t min_bytes, size_t max_bytes)
Definition: tls_reader.h:115
void client_hello(Client_Hello *client_hello)
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)
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:26
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:203
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
size_t length() const
Definition: symkey.h:25
virtual SymmetricKey psk(const std::string &type, const std::string &context, const std::string &identity)
std::unique_ptr< Public_Key > server_public_key
Definition: tls_client.cpp:38
void server_certs(Certificate *server_certs)
uint8_t major_version() const
Definition: tls_version.h:77
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
virtual bool hide_unknown_users() const
Definition: tls_policy.cpp:342
static std::vector< uint8_t > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
secure_vector< uint8_t > bits_of() const
Definition: symkey.h:31
std::string srp6_group_identifier(const BigInt &N, const BigInt &g)
Definition: srp6.cpp:53
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:170
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