Botan  2.7.0
Crypto and TLS for C++11
msg_finished.cpp
Go to the documentation of this file.
1 /*
2 * Finished Message
3 * (C) 2004-2006,2012 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/kdf.h>
10 #include <botan/internal/tls_handshake_io.h>
11 #include <botan/internal/tls_handshake_state.h>
12 
13 namespace Botan {
14 
15 namespace TLS {
16 
17 namespace {
18 
19 /*
20 * Compute the verify_data
21 */
22 std::vector<uint8_t> finished_compute_verify(const Handshake_State& state,
23  Connection_Side side)
24  {
25  const uint8_t TLS_CLIENT_LABEL[] = {
26  0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69,
27  0x73, 0x68, 0x65, 0x64 };
28 
29  const uint8_t TLS_SERVER_LABEL[] = {
30  0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6E, 0x69,
31  0x73, 0x68, 0x65, 0x64 };
32 
33  std::unique_ptr<KDF> prf(state.protocol_specific_prf());
34 
35  std::vector<uint8_t> input;
36  std::vector<uint8_t> label;
37  if(side == CLIENT)
38  label += std::make_pair(TLS_CLIENT_LABEL, sizeof(TLS_CLIENT_LABEL));
39  else
40  label += std::make_pair(TLS_SERVER_LABEL, sizeof(TLS_SERVER_LABEL));
41 
42  input += state.hash().final(state.version(), state.ciphersuite().prf_algo());
43 
44  return unlock(prf->derive_key(12, state.session_keys().master_secret(), input, label));
45  }
46 
47 }
48 
49 /*
50 * Create a new Finished message
51 */
53  Handshake_State& state,
54  Connection_Side side) : m_verification_data(finished_compute_verify( state, side ))
55  {
56  state.hash().update(io.send(*this));
57  }
58 
59 /*
60 * Serialize a Finished message
61 */
62 std::vector<uint8_t> Finished::serialize() const
63  {
64  return m_verification_data;
65  }
66 
67 /*
68 * Deserialize a Finished message
69 */
70 Finished::Finished(const std::vector<uint8_t>& buf) : m_verification_data(buf)
71  {}
72 
73 /*
74 * Verify a Finished message
75 */
77  Connection_Side side) const
78  {
79  std::vector<byte> computed_verify = finished_compute_verify(state, side);
80 
81 #if defined(BOTAN_UNSAFE_FUZZER_MODE)
82  return true;
83 #else
84  return (m_verification_data.size() == computed_verify.size()) &&
85  constant_time_compare(m_verification_data.data(), computed_verify.data(), computed_verify.size());
86 #endif
87  }
88 
89 }
90 
91 }
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.cpp:51
void update(const uint8_t in[], size_t length)
Definition: alg_id.cpp:13
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:95
Finished(Handshake_IO &io, Handshake_State &state, Connection_Side side)
bool verify(const Handshake_State &state, Connection_Side side) const