Botan 3.11.0
Crypto and TLS for C&
Botan::TLS::Transcript_Hash_State Class Reference

#include <tls_transcript_hash_13.h>

Public Member Functions

Transcript_Hash_State clone () const
const Transcript_Hashcurrent () const
Transcript_Hash_Stateoperator= (const Transcript_Hash_State &)=delete
Transcript_Hash_Stateoperator= (Transcript_Hash_State &&other) noexcept
const Transcript_Hashprevious () const
void set_algorithm (std::string_view algo_spec)
 Transcript_Hash_State ()
 Transcript_Hash_State (std::string_view algo_spec)
 Transcript_Hash_State (Transcript_Hash_State &&other) noexcept
const Transcript_Hashtruncated () const
void update (std::span< const uint8_t > serialized_message_s)
 ~Transcript_Hash_State ()

Static Public Member Functions

static Transcript_Hash_State recreate_after_hello_retry_request (std::string_view algo_spec, const Transcript_Hash_State &prev_transcript_hash_state)

Detailed Description

Wraps the behaviour of the TLS 1.3 transcript hash as described in RFC 8446 4.4.1. Particularly, it hides the complexity that the utilized hash algorithm might become evident only after receiving a server hello message.

Definition at line 32 of file tls_transcript_hash_13.h.

Constructor & Destructor Documentation

◆ Transcript_Hash_State() [1/3]

Botan::TLS::Transcript_Hash_State::Transcript_Hash_State ( )
default

◆ Transcript_Hash_State() [2/3]

Botan::TLS::Transcript_Hash_State::Transcript_Hash_State ( std::string_view algo_spec)
explicit

Definition at line 20 of file tls_transcript_hash_13.cpp.

20 {
21 set_algorithm(algo_spec);
22}
void set_algorithm(std::string_view algo_spec)

References set_algorithm().

◆ ~Transcript_Hash_State()

Botan::TLS::Transcript_Hash_State::~Transcript_Hash_State ( )
default

◆ Transcript_Hash_State() [3/3]

Botan::TLS::Transcript_Hash_State::Transcript_Hash_State ( Transcript_Hash_State && other)
defaultnoexcept

Member Function Documentation

◆ clone()

Transcript_Hash_State Botan::TLS::Transcript_Hash_State::clone ( ) const

Definition at line 211 of file tls_transcript_hash_13.cpp.

211 {
212 return *this;
213}

References Transcript_Hash_State().

Referenced by Botan::TLS::PSK::calculate_binders(), operator=(), and Botan::TLS::Client_Hello_13::retry().

◆ current()

const Transcript_Hash & Botan::TLS::Transcript_Hash_State::current ( ) const

returns the latest transcript hash (given an algorithm was already specified and some data was provided to update)

Definition at line 183 of file tls_transcript_hash_13.cpp.

183 {
184 BOTAN_STATE_CHECK(!m_current.empty());
185 return m_current;
186}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49

References BOTAN_STATE_CHECK.

Referenced by operator=().

◆ operator=() [1/2]

Transcript_Hash_State & Botan::TLS::Transcript_Hash_State::operator= ( const Transcript_Hash_State & )
delete

◆ operator=() [2/2]

Transcript_Hash_State & Botan::TLS::Transcript_Hash_State::operator= ( Transcript_Hash_State && other)
defaultnoexcept

◆ previous()

const Transcript_Hash & Botan::TLS::Transcript_Hash_State::previous ( ) const

returns the second-latest transcript hash throws if no 'current' was ever replaced by a call to update

Definition at line 188 of file tls_transcript_hash_13.cpp.

188 {
189 BOTAN_STATE_CHECK(!m_previous.empty());
190 return m_previous;
191}

References BOTAN_STATE_CHECK.

Referenced by operator=().

◆ recreate_after_hello_retry_request()

Transcript_Hash_State Botan::TLS::Transcript_Hash_State::recreate_after_hello_retry_request ( std::string_view algo_spec,
const Transcript_Hash_State & prev_transcript_hash_state )
static

Recreates a Transcript_Hash_State after receiving a Hello Retry Request. Note that the prev_transcript_hash_state must not have an hash algorithm set, yet. Furthermore it must contain exactly TWO unprocessed messages:

  • Client Hello 1, and
  • Hello Retry Request The result of this function is an ordinary transcript hash that can replace the previously used object in client and server implementations.

Definition at line 38 of file tls_transcript_hash_13.cpp.

39 {
40 // make sure that we have seen exactly 'client_hello' and 'hello_retry_request'
41 // before re-creating the transcript hash state
42 BOTAN_STATE_CHECK(prev_transcript_hash_state.m_hash == nullptr);
43 BOTAN_STATE_CHECK(prev_transcript_hash_state.m_unprocessed_transcript.size() == 2);
44
45 Transcript_Hash_State transcript_hash(algo_spec);
46
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();
49
50 const size_t hash_length = transcript_hash.m_hash->output_length();
51 BOTAN_ASSERT_NOMSG(hash_length < 256);
52
53 // RFC 8446 4.4.1
54 // [...], when the server responds to a ClientHello with a HelloRetryRequest,
55 // the value of ClientHello1 is replaced with a special synthetic handshake
56 // message of handshake type "message_hash" [(0xFE)] containing:
57 std::vector<uint8_t> message_hash;
58 message_hash.reserve(4 + hash_length);
59 message_hash.push_back(0xFE /* message type 'message_hash' RFC 8446 4. */);
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);
64
65 transcript_hash.update(message_hash);
66 transcript_hash.update(hello_retry_request);
67
68 return transcript_hash;
69}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Transcript_Hash_State(), and update().

Referenced by ~Transcript_Hash_State().

◆ set_algorithm()

void Botan::TLS::Transcript_Hash_State::set_algorithm ( std::string_view algo_spec)

Definition at line 198 of file tls_transcript_hash_13.cpp.

198 {
199 BOTAN_STATE_CHECK(m_hash == nullptr || m_hash->name() == algo_spec);
200 if(m_hash != nullptr) {
201 return;
202 }
203
204 m_hash = HashFunction::create_or_throw(algo_spec);
205 for(const auto& msg : m_unprocessed_transcript) {
206 update(msg);
207 }
208 m_unprocessed_transcript.clear();
209}
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:308
void update(std::span< const uint8_t > serialized_message_s)

References BOTAN_STATE_CHECK, Botan::HashFunction::create_or_throw(), and update().

Referenced by Botan::TLS::PSK::calculate_binders(), operator=(), and Transcript_Hash_State().

◆ truncated()

const Transcript_Hash & Botan::TLS::Transcript_Hash_State::truncated ( ) const

returns a truncated transcript hash (see RFC 8446 4.2.11.2)

This is useful for implementing PSK binders in the PSK extension of client hello. It is a transcript over a partially marshalled client hello message. This hash is available only if the last processed message was a client hello with a PSK extension.

throws if no 'truncated' hash is available

Definition at line 193 of file tls_transcript_hash_13.cpp.

193 {
194 BOTAN_STATE_CHECK(!m_truncated.empty());
195 return m_truncated;
196}

References BOTAN_STATE_CHECK.

Referenced by operator=().

◆ update()

void Botan::TLS::Transcript_Hash_State::update ( std::span< const uint8_t > serialized_message_s)

Definition at line 155 of file tls_transcript_hash_13.cpp.

155 {
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;
160
161 // Check whether we should generate a truncated hash for supporting PSK
162 // binder calculation or verification. See RFC 8446 4.2.11.2.
163 if(serialized_message_length > 0 && *serialized_message == static_cast<uint8_t>(Handshake_Type::ClientHello)) {
164 truncation_mark = find_client_hello_truncation_mark(serialized_message_s);
165 }
166
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);
171 } else {
172 m_truncated.clear();
173 m_hash->update(serialized_message, serialized_message_length);
174 }
175
176 m_previous = std::exchange(m_current, read_hash_state(m_hash));
177 } else {
178 m_unprocessed_transcript.push_back(
179 std::vector(serialized_message, serialized_message + serialized_message_length));
180 }
181}

References Botan::TLS::ClientHello.

Referenced by Botan::TLS::Handshake_Layer::next_message(), operator=(), Botan::TLS::Handshake_Layer::prepare_message(), recreate_after_hello_retry_request(), and set_algorithm().


The documentation for this class was generated from the following files: