9#include <botan/internal/tls_transcript_hash_13.h>
11#include <botan/internal/tls_reader.h>
12#include <botan/tls_messages.h>
13#include <botan/tls_exceptn.h>
25 : m_hash((other.m_hash != nullptr) ? other.m_hash->copy_state() : nullptr)
26 , m_unprocessed_transcript(other.m_unprocessed_transcript)
27 , m_current(other.m_current)
28 , m_previous(other.m_previous)
29 , m_truncated(other.m_truncated)
34 std::string_view algo_spec,
40 BOTAN_STATE_CHECK(prev_transcript_hash_state.m_unprocessed_transcript.size() == 2);
44 const auto& client_hello_1 = prev_transcript_hash_state.m_unprocessed_transcript.front();
45 const auto& hello_retry_request = prev_transcript_hash_state.m_unprocessed_transcript.back();
47 const size_t hash_length = ths.m_hash->output_length();
54 std::vector<uint8_t> message_hash;
55 message_hash.reserve(4 + hash_length);
56 message_hash.push_back(0xFE );
57 message_hash.push_back(0x00);
58 message_hash.push_back(0x00);
59 message_hash.push_back(
static_cast<uint8_t
>(hash_length));
60 message_hash += ths.m_hash->process(client_hello_1);
63 ths.
update(hello_retry_request);
81size_t find_client_hello_truncation_mark(std::span<const uint8_t> client_hello)
90 reader.discard_next(3);
93 reader.discard_next(2);
96 reader.discard_next(32);
99 const auto session_id_length = reader.get_byte();
100 reader.discard_next(session_id_length);
106 const auto ciphersuites_length = reader.get_uint16_t();
107 reader.discard_next(ciphersuites_length);
110 const auto compression_methods_length = reader.get_byte();
111 reader.discard_next(compression_methods_length);
114 const auto extensions_length = reader.get_uint16_t();
115 const auto extensions_offset = reader.read_so_far();
116 while(reader.has_remaining() && reader.read_so_far() - extensions_offset < extensions_length)
118 const auto ext_type =
static_cast<Extension_Code>(reader.get_uint16_t());
119 const auto ext_length = reader.get_uint16_t();
122 if(ext_type != Extension_Code::PresharedKey)
124 reader.discard_next(ext_length);
129 const auto identities_length = reader.get_uint16_t();
130 reader.discard_next(identities_length);
133 const auto binders_length = reader.peek_uint16_t();
134 if(binders_length != reader.remaining_bytes() - 2 )
136 throw TLS_Exception(Alert::IllegalParameter,
137 "Failed to truncate Client Hello that doesn't end on the PSK binders list");
145 return reader.read_so_far();
148std::vector<uint8_t> read_hash_state(std::unique_ptr<HashFunction>& hash)
153 return hash->copy_state()->final_stdvec();
160 auto serialized_message = serialized_message_s.data();
161 auto serialized_message_length = serialized_message_s.size();
162 if(m_hash !=
nullptr)
164 auto truncation_mark = serialized_message_length;
168 if(serialized_message_length > 0 &&
172 find_client_hello_truncation_mark(serialized_message_s);
175 if(truncation_mark < serialized_message_length)
177 m_hash->update(serialized_message, truncation_mark);
178 m_truncated = read_hash_state(m_hash);
179 m_hash->update(serialized_message + truncation_mark, serialized_message_length - truncation_mark);
184 m_hash->update(serialized_message, serialized_message_length);
187 m_previous = std::exchange(m_current, read_hash_state(m_hash));
191 m_unprocessed_transcript.push_back(std::vector(serialized_message, serialized_message + serialized_message_length));
216 if(m_hash !=
nullptr)
220 for(
const auto& msg : m_unprocessed_transcript)
224 m_unprocessed_transcript.clear();
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_STATE_CHECK(expr)
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
void update(std::span< const uint8_t > serialized_message_s)
const Transcript_Hash & current() const
Transcript_Hash_State clone() const
static Transcript_Hash_State recreate_after_hello_retry_request(std::string_view algo_spec, const Transcript_Hash_State &prev_transcript_hash_state)
void set_algorithm(std::string_view algo_spec)
const Transcript_Hash & previous() const
const Transcript_Hash & truncated() const
Transcript_Hash_State()=default
int(* update)(CTX *, const void *, CC_LONG len)
std::vector< uint8_t > Transcript_Hash