Botan  2.4.0
Crypto and TLS for C++11
tls_handshake_state.cpp
Go to the documentation of this file.
1 /*
2 * TLS Handshaking
3 * (C) 2004-2006,2011,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/internal/tls_handshake_state.h>
10 #include <botan/internal/tls_record.h>
11 #include <botan/tls_messages.h>
12 #include <botan/kdf.h>
13 #include <sstream>
14 
15 namespace Botan {
16 
17 namespace TLS {
18 
19 std::string Handshake_Message::type_string() const
20  {
22  }
23 
25  {
26  switch(type)
27  {
29  return "hello_verify_request";
30 
31  case HELLO_REQUEST:
32  return "hello_request";
33 
34  case CLIENT_HELLO:
35  return "client_hello";
36 
37  case SERVER_HELLO:
38  return "server_hello";
39 
40  case CERTIFICATE:
41  return "certificate";
42 
43  case CERTIFICATE_URL:
44  return "certificate_url";
45 
46  case CERTIFICATE_STATUS:
47  return "certificate_status";
48 
49  case SERVER_KEX:
50  return "server_key_exchange";
51 
53  return "certificate_request";
54 
55  case SERVER_HELLO_DONE:
56  return "server_hello_done";
57 
58  case CERTIFICATE_VERIFY:
59  return "certificate_verify";
60 
61  case CLIENT_KEX:
62  return "client_key_exchange";
63 
64  case NEW_SESSION_TICKET:
65  return "new_session_ticket";
66 
67  case HANDSHAKE_CCS:
68  return "change_cipher_spec";
69 
70  case FINISHED:
71  return "finished";
72 
73  case HANDSHAKE_NONE:
74  return "invalid";
75  }
76 
78  "Unknown TLS handshake message type " + std::to_string(type));
79  }
80 
81 namespace {
82 
83 uint32_t bitmask_for_handshake_type(Handshake_Type type)
84  {
85  switch(type)
86  {
88  return (1 << 0);
89 
90  case HELLO_REQUEST:
91  return (1 << 1);
92 
93  case CLIENT_HELLO:
94  return (1 << 2);
95 
96  case SERVER_HELLO:
97  return (1 << 3);
98 
99  case CERTIFICATE:
100  return (1 << 4);
101 
102  case CERTIFICATE_URL:
103  return (1 << 5);
104 
105  case CERTIFICATE_STATUS:
106  return (1 << 6);
107 
108  case SERVER_KEX:
109  return (1 << 7);
110 
111  case CERTIFICATE_REQUEST:
112  return (1 << 8);
113 
114  case SERVER_HELLO_DONE:
115  return (1 << 9);
116 
117  case CERTIFICATE_VERIFY:
118  return (1 << 10);
119 
120  case CLIENT_KEX:
121  return (1 << 11);
122 
123  case NEW_SESSION_TICKET:
124  return (1 << 12);
125 
126  case HANDSHAKE_CCS:
127  return (1 << 13);
128 
129  case FINISHED:
130  return (1 << 14);
131 
132  // allow explicitly disabling new handshakes
133  case HANDSHAKE_NONE:
134  return 0;
135  }
136 
138  "Unknown TLS handshake message type " + std::to_string(type));
139  }
140 
141 std::string handshake_mask_to_string(uint32_t mask)
142  {
143  const Handshake_Type types[] = {
146  CLIENT_HELLO,
147  CERTIFICATE,
150  SERVER_KEX,
154  CLIENT_KEX,
157  FINISHED
158  };
159 
160  std::ostringstream o;
161  bool empty = true;
162 
163  for(auto&& t : types)
164  {
165  if(mask & bitmask_for_handshake_type(t))
166  {
167  if(!empty)
168  o << ",";
169  o << handshake_type_to_string(t);
170  empty = false;
171  }
172  }
173 
174  return o.str();
175  }
176 
177 }
178 
179 /*
180 * Initialize the SSL/TLS Handshake State
181 */
183  m_callbacks(cb),
184  m_handshake_io(io),
185  m_version(m_handshake_io->initial_record_version())
186  {
187  }
188 
190  {
191  m_callbacks.tls_inspect_handshake_msg(msg);
192  }
193 
195  {
196  note_message(hello_verify);
197 
198  m_client_hello->update_hello_cookie(hello_verify);
199  hash().reset();
200  hash().update(handshake_io().send(*m_client_hello));
201  note_message(*m_client_hello);
202  }
203 
205  {
206  m_client_hello.reset(client_hello);
207  note_message(*m_client_hello);
208  }
209 
211  {
212  m_server_hello.reset(server_hello);
213  m_ciphersuite = Ciphersuite::by_id(m_server_hello->ciphersuite());
214  note_message(*m_server_hello);
215  }
216 
218  {
219  m_server_certs.reset(server_certs);
220  note_message(*m_server_certs);
221  }
222 
224  {
225  m_server_cert_status.reset(server_cert_status);
226  note_message(*m_server_cert_status);
227  }
228 
230  {
231  m_server_kex.reset(server_kex);
232  note_message(*m_server_kex);
233  }
234 
236  {
237  m_cert_req.reset(cert_req);
238  note_message(*m_cert_req);
239  }
240 
242  {
243  m_server_hello_done.reset(server_hello_done);
244  note_message(*m_server_hello_done);
245  }
246 
248  {
249  m_client_certs.reset(client_certs);
250  note_message(*m_client_certs);
251  }
252 
254  {
255  m_client_kex.reset(client_kex);
256  note_message(*m_client_kex);
257  }
258 
260  {
261  m_client_verify.reset(client_verify);
262  note_message(*m_client_verify);
263  }
264 
266  {
267  m_new_session_ticket.reset(new_session_ticket);
268  note_message(*m_new_session_ticket);
269  }
270 
272  {
273  m_server_finished.reset(server_finished);
274  note_message(*m_server_finished);
275  }
276 
278  {
279  m_client_finished.reset(client_finished);
280  note_message(*m_client_finished);
281  }
282 
284  {
285  m_version = version;
286  }
287 
289  {
290  m_session_keys = Session_Keys(this, client_kex()->pre_master_secret(), false);
291  }
292 
294  {
295  m_session_keys = Session_Keys(this, resume_master_secret, true);
296  }
297 
299  {
300  const uint32_t mask = bitmask_for_handshake_type(handshake_msg);
301 
302  m_hand_received_mask |= mask;
303 
304  const bool ok = (m_hand_expecting_mask & mask) != 0; // overlap?
305 
306  if(!ok)
307  throw Unexpected_Message("Unexpected state transition in handshake, got type " +
308  std::to_string(handshake_msg) +
309  " expected " + handshake_mask_to_string(m_hand_expecting_mask) +
310  " received " + handshake_mask_to_string(m_hand_received_mask));
311 
312  /* We don't know what to expect next, so force a call to
313  set_expected_next; if it doesn't happen, the next transition
314  check will always fail which is what we want.
315  */
316  m_hand_expecting_mask = 0;
317  }
318 
320  {
321  m_hand_expecting_mask |= bitmask_for_handshake_type(handshake_msg);
322  }
323 
325  {
326  const uint32_t mask = bitmask_for_handshake_type(handshake_msg);
327 
328  return (m_hand_received_mask & mask) != 0;
329  }
330 
331 std::pair<Handshake_Type, std::vector<uint8_t>>
333  {
334  const bool expecting_ccs =
335  (bitmask_for_handshake_type(HANDSHAKE_CCS) & m_hand_expecting_mask) != 0;
336 
337  return m_handshake_io->get_next_record(expecting_ccs);
338  }
339 
341  {
342 #if defined(BOTAN_HAS_SRP6)
343  // Authenticated via the successful key exchange
344  if(ciphersuite().valid() && ciphersuite().kex_algo() == "SRP_SHA")
345  return client_hello()->srp_identifier();
346 #endif
347 
348  return "";
349  }
350 
351 
352 std::vector<uint8_t> Handshake_State::session_ticket() const
353  {
354  if(new_session_ticket() && !new_session_ticket()->ticket().empty())
355  return new_session_ticket()->ticket();
356 
357  return client_hello()->session_ticket();
358  }
359 
361  {
362  if(version().supports_ciphersuite_specific_prf())
363  {
364  const std::string prf_algo = ciphersuite().prf_algo();
365 
366  if(prf_algo == "MD5" || prf_algo == "SHA-1")
367  return get_kdf("TLS-12-PRF(SHA-256)");
368 
369  return get_kdf("TLS-12-PRF(" + prf_algo + ")");
370  }
371 
372  // Old PRF used in TLS v1.0, v1.1 and DTLS v1.0
373  return get_kdf("TLS-PRF");
374  }
375 
376 namespace {
377 
378 std::string choose_hash(const std::string& sig_algo,
379  std::vector<std::pair<std::string, std::string>>& supported_algos,
380  Protocol_Version negotiated_version,
381  const Policy& policy)
382  {
383  if(!negotiated_version.supports_negotiable_signature_algorithms())
384  {
385  if(sig_algo == "RSA")
386  return "Parallel(MD5,SHA-160)";
387 
388  if(sig_algo == "DSA")
389  return "SHA-1";
390 
391  if(sig_algo == "ECDSA")
392  return "SHA-1";
393 
394  throw Internal_Error("Unknown TLS signature algo " + sig_algo);
395  }
396 
397  if(!supported_algos.empty())
398  {
399  const std::vector<std::string> hashes = policy.allowed_signature_hashes();
400 
401  /*
402  * Choose our most preferred hash that the counterparty supports
403  * in pairing with the signature algorithm we want to use.
404  */
405  for(std::string hash : hashes)
406  {
407  for(auto algo : supported_algos)
408  {
409  if(algo.first == hash && algo.second == sig_algo)
410  return hash;
411  }
412  }
413  }
414 
415  // TLS v1.2 default hash if the counterparty sent nothing
416  return "SHA-1";
417  }
418 
419 }
420 
421 std::pair<std::string, Signature_Format>
423  std::string& hash_algo_out,
424  std::string& sig_algo_out,
425  bool for_client_auth,
426  const Policy& policy) const
427  {
428  const std::string sig_algo = key.algo_name();
429 
430  std::vector<std::pair<std::string, std::string>> supported_algos =
431  (for_client_auth) ? cert_req()->supported_algos() : client_hello()->supported_algos();
432 
433  const std::string hash_algo = choose_hash(sig_algo,
434  supported_algos,
435  this->version(),
436  policy);
437 
438  if(this->version().supports_negotiable_signature_algorithms())
439  {
440  // We skip this check for v1.0 since you're stuck with SHA-1 regardless
441 
442  if(!policy.allowed_signature_hash(hash_algo))
443  {
445  "Policy refuses to accept signing with any hash supported by peer");
446  }
447 
448  hash_algo_out = hash_algo;
449  sig_algo_out = sig_algo;
450  }
451 
452  if(sig_algo == "RSA")
453  {
454  const std::string padding = "EMSA3(" + hash_algo + ")";
455 
456  return std::make_pair(padding, IEEE_1363);
457  }
458  else if(sig_algo == "DSA" || sig_algo == "ECDSA")
459  {
460  const std::string padding = "EMSA1(" + hash_algo + ")";
461 
462  return std::make_pair(padding, DER_SEQUENCE);
463  }
464 
465  throw Invalid_Argument(sig_algo + " is invalid/unknown for TLS signatures");
466  }
467 
468 namespace {
469 
470 bool supported_algos_include(
471  const std::vector<std::pair<std::string, std::string>>& algos,
472  const std::string& key_type,
473  const std::string& hash_type)
474  {
475  for(auto&& algo : algos)
476  {
477  if(algo.first == hash_type && algo.second == key_type)
478  {
479  return true;
480  }
481  }
482 
483  return false;
484  }
485 
486 }
487 
488 std::pair<std::string, Signature_Format>
490  const std::string& input_hash_algo,
491  const std::string& input_sig_algo,
492  bool for_client_auth,
493  const Policy& policy) const
494  {
495  const std::string key_type = key.algo_name();
496 
497  if(!policy.allowed_signature_method(key_type))
498  {
500  "Rejecting " + key_type + " signature");
501  }
502 
503  std::string hash_algo;
504 
505  if(this->version().supports_negotiable_signature_algorithms())
506  {
507  if(input_sig_algo != key_type)
508  throw Decoding_Error("Counterparty sent inconsistent key and sig types");
509 
510  if(input_hash_algo == "")
511  throw Decoding_Error("Counterparty did not send hash/sig IDS");
512 
513  hash_algo = input_hash_algo;
514 
515  if(for_client_auth && !cert_req())
516  {
518  "No certificate verify set");
519  }
520 
521  /*
522  Confirm the signature type we just received against the
523  supported_algos list that we sent; it better be there.
524  */
525 
526  const auto supported_algos =
527  for_client_auth ? cert_req()->supported_algos() :
529 
530  if(!supported_algos_include(supported_algos, key_type, hash_algo))
531  {
533  "TLS signature extension did not allow for " +
534  key_type + "/" + hash_algo + " signature");
535  }
536  }
537  else
538  {
539  if(input_hash_algo != "" || input_sig_algo != "")
540  throw Decoding_Error("Counterparty sent hash/sig IDs with old version");
541 
542  if(key_type == "RSA")
543  {
544  hash_algo = "Parallel(MD5,SHA-160)";
545  }
546  else if(key_type == "DSA" || key_type == "ECDSA")
547  {
548  hash_algo = "SHA-1";
549  }
550  else
551  {
552  throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures");
553  }
554 
555  /*
556  There is no check on the acceptability of a v1.0/v1.1 hash type,
557  since it's implicit with use of the protocol
558  */
559  }
560 
561  if(key_type == "RSA")
562  {
563  const std::string padding = "EMSA3(" + hash_algo + ")";
564  return std::make_pair(padding, IEEE_1363);
565  }
566  else if(key_type == "DSA" || key_type == "ECDSA")
567  {
568  const std::string padding = "EMSA1(" + hash_algo + ")";
569  return std::make_pair(padding, DER_SEQUENCE);
570  }
571 
572  throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures");
573  }
574 
575 }
576 
577 }
const Client_Key_Exchange * client_kex() const
std::vector< uint8_t > session_ticket() const
std::vector< uint8_t > session_ticket() const
std::pair< std::string, Signature_Format > parse_sig_format(const Public_Key &key, const std::string &hash_algo, const std::string &sig_algo, bool for_client_auth, const Policy &policy) const
std::string prf_algo() const
const Server_Hello * server_hello() const
virtual std::string algo_name() const =0
const Certificate * server_certs() const
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:108
Handshake_State(Handshake_IO *io, Callbacks &callbacks)
const Finished * server_finished() const
virtual std::vector< std::string > allowed_signature_hashes() const
Definition: tls_policy.cpp:48
std::pair< std::string, Signature_Format > choose_sig_format(const Private_Key &key, std::string &hash_algo, std::string &sig_algo, bool for_client_auth, const Policy &policy) const
const Server_Key_Exchange * server_kex() const
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
const Ciphersuite & ciphersuite() const
void set_version(const Protocol_Version &version)
const Certificate_Req * cert_req() const
const Certificate_Verify * client_verify() const
const Certificate_Status * server_cert_status() const
std::pair< Handshake_Type, std::vector< uint8_t > > get_next_handshake_msg()
const Finished * client_finished() const
bool allowed_signature_method(const std::string &sig_method) const
Definition: tls_policy.cpp:97
void update(const uint8_t in[], size_t length)
const Certificate * client_certs() const
KDF * get_kdf(const std::string &algo_spec)
Definition: kdf.cpp:236
bool allowed_signature_hash(const std::string &hash) const
Definition: tls_policy.cpp:102
Definition: alg_id.cpp:13
bool received_handshake_msg(Handshake_Type msg_type) const
void confirm_transition_to(Handshake_Type msg_type)
secure_vector< uint8_t > resume_master_secret
Definition: tls_client.cpp:41
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:22
virtual Handshake_Type type() const =0
std::vector< std::pair< std::string, std::string > > supported_algos() const
void note_message(const Handshake_Message &msg)
Definition: kdf.h:20
const std::vector< uint8_t > & ticket() const
Definition: tls_messages.h:598
const New_Session_Ticket * new_session_ticket() const
const Server_Hello_Done * server_hello_done() const
static Ciphersuite by_id(uint16_t suite)
void hello_verify_request(const Hello_Verify_Request &hello_verify)
std::vector< std::pair< std::string, std::string > > supported_algos() const
Definition: tls_messages.h:414
Protocol_Version version() const
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
virtual void tls_inspect_handshake_msg(const Handshake_Message &message)
const Client_Hello * client_hello() const
const char * handshake_type_to_string(Handshake_Type type)
void set_expected_next(Handshake_Type msg_type)