9#include <botan/internal/tls_transcript_hash_13.h>
11#include <botan/hash.h>
12#include <botan/tls_exceptn.h>
13#include <botan/tls_extensions.h>
14#include <botan/internal/tls_reader.h>
32 m_hash((other.m_hash != nullptr) ? other.m_hash->copy_state() : nullptr),
33 m_unprocessed_transcript(other.m_unprocessed_transcript),
34 m_current(other.m_current),
35 m_previous(other.m_previous),
36 m_truncated(other.m_truncated) {}
43 BOTAN_STATE_CHECK(prev_transcript_hash_state.m_unprocessed_transcript.size() == 2);
47 const auto& client_hello_1 = prev_transcript_hash_state.m_unprocessed_transcript.front();
48 const auto& hello_retry_request = prev_transcript_hash_state.m_unprocessed_transcript.back();
50 const size_t hash_length = transcript_hash.m_hash->output_length();
57 std::vector<uint8_t> message_hash;
58 message_hash.reserve(4 + hash_length);
59 message_hash.push_back(0xFE );
60 message_hash.push_back(0x00);
61 message_hash.push_back(0x00);
62 message_hash.push_back(
static_cast<uint8_t
>(hash_length));
63 message_hash += transcript_hash.m_hash->process(client_hello_1);
65 transcript_hash.
update(message_hash);
66 transcript_hash.
update(hello_retry_request);
68 return transcript_hash;
84size_t find_client_hello_truncation_mark(std::span<const uint8_t> client_hello) {
91 reader.discard_next(3);
94 reader.discard_next(2);
97 reader.discard_next(32);
100 const auto session_id_length = reader.get_byte();
101 reader.discard_next(session_id_length);
107 const auto ciphersuites_length = reader.get_uint16_t();
108 reader.discard_next(ciphersuites_length);
111 const auto compression_methods_length = reader.get_byte();
112 reader.discard_next(compression_methods_length);
115 const auto extensions_length = reader.get_uint16_t();
116 const auto extensions_offset = reader.read_so_far();
117 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();
123 reader.discard_next(ext_length);
128 const auto identities_length = reader.get_uint16_t();
129 reader.discard_next(identities_length);
132 const auto binders_length = reader.peek_uint16_t();
133 if(binders_length != reader.remaining_bytes() - 2 ) {
134 throw TLS_Exception(Alert::IllegalParameter,
135 "Failed to truncate Client Hello that doesn't end on the PSK binders list");
143 return reader.read_so_far();
146std::vector<uint8_t> read_hash_state(std::unique_ptr<HashFunction>& hash) {
150 return hash->copy_state()->final_stdvec();
156 const auto* serialized_message = serialized_message_s.data();
157 auto serialized_message_length = serialized_message_s.size();
158 if(m_hash !=
nullptr) {
159 auto truncation_mark = serialized_message_length;
164 truncation_mark = find_client_hello_truncation_mark(serialized_message_s);
167 if(truncation_mark < serialized_message_length) {
168 m_hash->update(serialized_message, truncation_mark);
169 m_truncated = read_hash_state(m_hash);
170 m_hash->update(serialized_message + truncation_mark, serialized_message_length - truncation_mark);
173 m_hash->update(serialized_message, serialized_message_length);
176 m_previous = std::exchange(m_current, read_hash_state(m_hash));
178 m_unprocessed_transcript.push_back(
179 std::vector(serialized_message, serialized_message + serialized_message_length));
200 if(m_hash !=
nullptr) {
205 for(
const auto& msg : m_unprocessed_transcript) {
208 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 & operator=(const Transcript_Hash_State &)=delete
std::vector< uint8_t > Transcript_Hash