Botan 2.19.1
Crypto and TLS for C&
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
13namespace Botan {
14
15namespace TLS {
16
17namespace {
18
19/*
20* Compute the verify_data
21*/
22std::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*/
62std::vector<uint8_t> Finished::serialize() const
63 {
64 return m_verification_data;
65 }
66
67/*
68* Deserialize a Finished message
69*/
70Finished::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}
Finished(Handshake_IO &io, Handshake_State &state, Connection_Side side)
bool verify(const Handshake_State &state, Connection_Side side) const
void update(const uint8_t in[], size_t length)
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
Definition: alg_id.cpp:13
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:72
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:82