9#include <botan/internal/tls_transcript_hash_13.h>
11#include <botan/tls_exceptn.h>
12#include <botan/tls_messages.h>
13#include <botan/internal/tls_reader.h>
24 m_hash((other.m_hash != nullptr) ? other.m_hash->copy_state() : nullptr),
25 m_unprocessed_transcript(other.m_unprocessed_transcript),
26 m_current(other.m_current),
27 m_previous(other.m_previous),
28 m_truncated(other.m_truncated) {}
35 BOTAN_STATE_CHECK(prev_transcript_hash_state.m_unprocessed_transcript.size() == 2);
39 const auto& client_hello_1 = prev_transcript_hash_state.m_unprocessed_transcript.front();
40 const auto& hello_retry_request = prev_transcript_hash_state.m_unprocessed_transcript.back();
42 const size_t hash_length = ths.m_hash->output_length();
49 std::vector<uint8_t> message_hash;
50 message_hash.reserve(4 + hash_length);
51 message_hash.push_back(0xFE );
52 message_hash.push_back(0x00);
53 message_hash.push_back(0x00);
54 message_hash.push_back(
static_cast<uint8_t
>(hash_length));
55 message_hash += ths.m_hash->process(client_hello_1);
58 ths.
update(hello_retry_request);
76size_t find_client_hello_truncation_mark(std::span<const uint8_t> client_hello) {
83 reader.discard_next(3);
86 reader.discard_next(2);
89 reader.discard_next(32);
92 const auto session_id_length = reader.get_byte();
93 reader.discard_next(session_id_length);
99 const auto ciphersuites_length = reader.get_uint16_t();
100 reader.discard_next(ciphersuites_length);
103 const auto compression_methods_length = reader.get_byte();
104 reader.discard_next(compression_methods_length);
107 const auto extensions_length = reader.get_uint16_t();
108 const auto extensions_offset = reader.read_so_far();
109 while(reader.has_remaining() && reader.read_so_far() - extensions_offset < extensions_length) {
110 const auto ext_type =
static_cast<Extension_Code>(reader.get_uint16_t());
111 const auto ext_length = reader.get_uint16_t();
115 reader.discard_next(ext_length);
120 const auto identities_length = reader.get_uint16_t();
121 reader.discard_next(identities_length);
124 const auto binders_length = reader.peek_uint16_t();
125 if(binders_length != reader.remaining_bytes() - 2 ) {
126 throw TLS_Exception(Alert::IllegalParameter,
127 "Failed to truncate Client Hello that doesn't end on the PSK binders list");
135 return reader.read_so_far();
138std::vector<uint8_t> read_hash_state(std::unique_ptr<HashFunction>& hash) {
142 return hash->copy_state()->final_stdvec();
148 auto serialized_message = serialized_message_s.data();
149 auto serialized_message_length = serialized_message_s.size();
150 if(m_hash !=
nullptr) {
151 auto truncation_mark = serialized_message_length;
156 truncation_mark = find_client_hello_truncation_mark(serialized_message_s);
159 if(truncation_mark < serialized_message_length) {
160 m_hash->update(serialized_message, truncation_mark);
161 m_truncated = read_hash_state(m_hash);
162 m_hash->update(serialized_message + truncation_mark, serialized_message_length - truncation_mark);
165 m_hash->update(serialized_message, serialized_message_length);
168 m_previous = std::exchange(m_current, read_hash_state(m_hash));
170 m_unprocessed_transcript.push_back(
171 std::vector(serialized_message, serialized_message + serialized_message_length));
192 if(m_hash !=
nullptr) {
197 for(
const auto& msg : m_unprocessed_transcript) {
200 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