Botan 3.6.1
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 &&)=default
 
const Transcript_Hashprevious () const
 
void set_algorithm (std::string_view algo_spec)
 
 Transcript_Hash_State ()=default
 
 Transcript_Hash_State (std::string_view algo_spec)
 
 Transcript_Hash_State (Transcript_Hash_State &&)=default
 
const Transcript_Hashtruncated () const
 
void update (std::span< const uint8_t > serialized_message_s)
 
 ~Transcript_Hash_State ()=default
 

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 28 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)

Definition at line 19 of file tls_transcript_hash_13.cpp.

19 {
20 set_algorithm(algo_spec);
21}
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 && )
default

Member Function Documentation

◆ clone()

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

Definition at line 203 of file tls_transcript_hash_13.cpp.

203 {
204 return *this;
205}

Referenced by Botan::TLS::PSK::calculate_binders(), 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 175 of file tls_transcript_hash_13.cpp.

175 {
176 BOTAN_STATE_CHECK(!m_current.empty());
177 return m_current;
178}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:41

References BOTAN_STATE_CHECK.

◆ 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 && )
default

◆ 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 180 of file tls_transcript_hash_13.cpp.

180 {
181 BOTAN_STATE_CHECK(!m_previous.empty());
182 return m_previous;
183}

References BOTAN_STATE_CHECK.

◆ 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 30 of file tls_transcript_hash_13.cpp.

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

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, and update().

◆ set_algorithm()

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

Definition at line 190 of file tls_transcript_hash_13.cpp.

190 {
191 BOTAN_STATE_CHECK(m_hash == nullptr || m_hash->name() == algo_spec);
192 if(m_hash != nullptr) {
193 return;
194 }
195
196 m_hash = HashFunction::create_or_throw(algo_spec);
197 for(const auto& msg : m_unprocessed_transcript) {
198 update(msg);
199 }
200 m_unprocessed_transcript.clear();
201}
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:298
int(* update)(CTX *, const void *, CC_LONG len)

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

Referenced by Botan::TLS::PSK::calculate_binders(), 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 185 of file tls_transcript_hash_13.cpp.

185 {
186 BOTAN_STATE_CHECK(!m_truncated.empty());
187 return m_truncated;
188}

References BOTAN_STATE_CHECK.

◆ update()

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

Definition at line 147 of file tls_transcript_hash_13.cpp.

147 {
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;
152
153 // Check whether we should generate a truncated hash for supporting PSK
154 // binder calculation or verification. See RFC 8446 4.2.11.2.
155 if(serialized_message_length > 0 && *serialized_message == static_cast<uint8_t>(Handshake_Type::ClientHello)) {
156 truncation_mark = find_client_hello_truncation_mark(serialized_message_s);
157 }
158
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);
163 } else {
164 m_truncated.clear();
165 m_hash->update(serialized_message, serialized_message_length);
166 }
167
168 m_previous = std::exchange(m_current, read_hash_state(m_hash));
169 } else {
170 m_unprocessed_transcript.push_back(
171 std::vector(serialized_message, serialized_message + serialized_message_length));
172 }
173}

References Botan::TLS::ClientHello.

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


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