Botan 3.5.0
Crypto and TLS for C&
Botan::TLS::Cipher_State Class Reference

#include <tls_cipher_state.h>

Public Types

enum class  PSK_Type { Resumption , External }
 

Public Member Functions

void advance_with_client_finished (const Transcript_Hash &transcript_hash)
 
void advance_with_client_hello (const Transcript_Hash &transcript_hash, const Secret_Logger &channel)
 
void advance_with_server_finished (const Transcript_Hash &transcript_hash, const Secret_Logger &channel)
 
void advance_with_server_hello (const Ciphersuite &cipher, secure_vector< uint8_t > &&shared_secret, const Transcript_Hash &transcript_hash, const Secret_Logger &channel)
 
bool can_decrypt_application_traffic () const
 
bool can_encrypt_application_traffic () const
 
bool can_export_keys () const
 
void clear_read_keys ()
 
void clear_write_keys ()
 
size_t decrypt_output_length (size_t input_length) const
 
uint64_t decrypt_record_fragment (const std::vector< uint8_t > &header, secure_vector< uint8_t > &encrypted_fragment)
 
size_t encrypt_output_length (size_t input_length) const
 
uint64_t encrypt_record_fragment (const std::vector< uint8_t > &header, secure_vector< uint8_t > &fragment)
 
secure_vector< uint8_t > export_key (std::string_view label, std::string_view context, size_t length) const
 
std::vector< uint8_t > finished_mac (const Transcript_Hash &transcript_hash) const
 
std::string hash_algorithm () const
 
bool is_compatible_with (const Ciphersuite &cipher) const
 
size_t minimum_decryption_input_length () const
 
bool must_expect_unprotected_alert_traffic () const
 
Ticket_Nonce next_ticket_nonce ()
 
secure_vector< uint8_t > psk (const Ticket_Nonce &nonce) const
 
std::vector< uint8_t > psk_binder_mac (const Transcript_Hash &transcript_hash_with_truncated_client_hello) const
 
void update_read_keys (const Secret_Logger &channel)
 
void update_write_keys (const Secret_Logger &channel)
 
bool verify_peer_finished_mac (const Transcript_Hash &transcript_hash, const std::vector< uint8_t > &peer_mac) const
 
 ~Cipher_State ()
 

Static Public Member Functions

static std::unique_ptr< Cipher_Stateinit_with_psk (Connection_Side side, PSK_Type type, secure_vector< uint8_t > &&psk, std::string_view prf_algo)
 
static std::unique_ptr< Cipher_Stateinit_with_server_hello (Connection_Side side, secure_vector< uint8_t > &&shared_secret, const Ciphersuite &cipher, const Transcript_Hash &transcript_hash, const Secret_Logger &channel)
 

Detailed Description

This class implements the key schedule for TLS 1.3 as described in RFC 8446 7.1.

Internally, it reflects the state machine pictured in the same RFC section. It provides the following entry points and state advancement methods that each facilitate certain cryptographic functionality:

While encrypting and decrypting records (RFC 8446 5.2) Cipher_State internally keeps track of the current sequence numbers (RFC 8446 5.3) to calculate the correct Per-Record Nonce. Sequence numbers are reset appropriately, whenever traffic secrets change.

Handshake finished MAC calculation and verification is described in RFC 8446 4.4.4.

PSKs calculation is described in RFC 8446 4.6.1.

Definition at line 62 of file tls_cipher_state.h.

Member Enumeration Documentation

◆ PSK_Type

Enumerator
Resumption 
External 

Definition at line 64 of file tls_cipher_state.h.

64 {
66 External, // currently not implemented
67 };

Constructor & Destructor Documentation

◆ ~Cipher_State()

Botan::TLS::Cipher_State::~Cipher_State ( )
default

Member Function Documentation

◆ advance_with_client_finished()

void Botan::TLS::Cipher_State::advance_with_client_finished ( const Transcript_Hash & transcript_hash)

Transition to the final internal state allowing to create resumptions.

Definition at line 205 of file tls_cipher_state.cpp.

205 {
206 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic);
207
208 zap(m_finished_key);
209 zap(m_peer_finished_key);
210
211 // With the client's Finished message, the handshake is complete and
212 // we can process client application data.
213 if(m_connection_side == Connection_Side::Server) {
214 derive_read_traffic_key(m_read_application_traffic_secret);
215 } else {
216 derive_write_traffic_key(m_write_application_traffic_secret);
217 }
218
219 const auto master_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));
220
221 m_resumption_master_secret = derive_secret(master_secret, "res master", transcript_hash);
222
223 // This was the final state change; the salt is no longer needed.
224 zap(m_salt);
225
226 m_state = State::Completed;
227}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:117
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61

References BOTAN_ASSERT_NOMSG, Botan::TLS::Server, and Botan::zap().

◆ advance_with_client_hello()

void Botan::TLS::Cipher_State::advance_with_client_hello ( const Transcript_Hash & transcript_hash,
const Secret_Logger & channel )

Transition internal secrets/keys for transporting early application data. Note that this state transition is legal only for handshakes using PSK.

Definition at line 141 of file tls_cipher_state.cpp.

141 {
142 BOTAN_ASSERT_NOMSG(m_state == State::PskBinder);
143
144 zap(m_binder_key);
145
146 // TODO: Currently 0-RTT is not yet implemented, hence we don't derive the
147 // early traffic secret for now.
148 //
149 // const auto client_early_traffic_secret = derive_secret(m_early_secret, "c e traffic", transcript_hash);
150 // derive_write_traffic_key(client_early_traffic_secret);
151
152 m_exporter_master_secret = derive_secret(m_early_secret, "e exp master", transcript_hash);
153
154 // draft-thomson-tls-keylogfile-00 Section 3.1
155 // An implementation of TLS 1.3 use the label
156 // "EARLY_EXPORTER_MASTER_SECRET" to identify the secret that is using for
157 // early exporters
158 loggger.maybe_log_secret("EARLY_EXPORTER_MASTER_SECRET", m_exporter_master_secret);
159
160 m_salt = derive_secret(m_early_secret, "derived", empty_hash());
161 zap(m_early_secret);
162
163 m_state = State::EarlyTraffic;
164}

References BOTAN_ASSERT_NOMSG, Botan::TLS::Secret_Logger::maybe_log_secret(), and Botan::zap().

◆ advance_with_server_finished()

void Botan::TLS::Cipher_State::advance_with_server_finished ( const Transcript_Hash & transcript_hash,
const Secret_Logger & channel )

Transition internal secrets/keys for transporting application data.

Definition at line 166 of file tls_cipher_state.cpp.

166 {
167 BOTAN_ASSERT_NOMSG(m_state == State::HandshakeTraffic);
168
169 const auto master_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));
170
171 auto client_application_traffic_secret = derive_secret(master_secret, "c ap traffic", transcript_hash);
172 auto server_application_traffic_secret = derive_secret(master_secret, "s ap traffic", transcript_hash);
173
174 // draft-thomson-tls-keylogfile-00 Section 3.1
175 // An implementation of TLS 1.3 use the label "CLIENT_TRAFFIC_SECRET_0"
176 // and "SERVER_TRAFFIC_SECRET_0" to identify the secrets are using to
177 // protect the connection.
178 loggger.maybe_log_secret("CLIENT_TRAFFIC_SECRET_0", client_application_traffic_secret);
179 loggger.maybe_log_secret("SERVER_TRAFFIC_SECRET_0", server_application_traffic_secret);
180
181 // Note: the secrets for processing client's application data
182 // are not derived before the client's Finished message
183 // was seen and the handshake can be considered finished.
184 if(m_connection_side == Connection_Side::Server) {
185 derive_write_traffic_key(server_application_traffic_secret);
186 m_read_application_traffic_secret = std::move(client_application_traffic_secret);
187 m_write_application_traffic_secret = std::move(server_application_traffic_secret);
188 } else {
189 derive_read_traffic_key(server_application_traffic_secret);
190 m_read_application_traffic_secret = std::move(server_application_traffic_secret);
191 m_write_application_traffic_secret = std::move(client_application_traffic_secret);
192 }
193
194 m_exporter_master_secret = derive_secret(master_secret, "exp master", transcript_hash);
195
196 // draft-thomson-tls-keylogfile-00 Section 3.1
197 // An implementation of TLS 1.3 use the label "EXPORTER_SECRET" to
198 // identify the secret that is used in generating exporters(rfc8446
199 // Section 7.5).
200 loggger.maybe_log_secret("EXPORTER_SECRET", m_exporter_master_secret);
201
202 m_state = State::ServerApplicationTraffic;
203}

References BOTAN_ASSERT_NOMSG, Botan::TLS::Secret_Logger::maybe_log_secret(), and Botan::TLS::Server.

◆ advance_with_server_hello()

void Botan::TLS::Cipher_State::advance_with_server_hello ( const Ciphersuite & cipher,
secure_vector< uint8_t > && shared_secret,
const Transcript_Hash & transcript_hash,
const Secret_Logger & channel )

Transition internal secrets/keys for transporting handshake data.

Definition at line 485 of file tls_cipher_state.cpp.

488 {
489 BOTAN_ASSERT_NOMSG(m_state == State::EarlyTraffic);
490 BOTAN_ASSERT_NOMSG(!m_encrypt);
491 BOTAN_ASSERT_NOMSG(!m_decrypt);
493
494 m_encrypt = AEAD_Mode::create_or_throw(cipher.cipher_algo(), Cipher_Dir::Encryption);
495 m_decrypt = AEAD_Mode::create_or_throw(cipher.cipher_algo(), Cipher_Dir::Decryption);
496
497 const auto handshake_secret = hkdf_extract(std::move(shared_secret));
498
499 const auto client_handshake_traffic_secret = derive_secret(handshake_secret, "c hs traffic", transcript_hash);
500 const auto server_handshake_traffic_secret = derive_secret(handshake_secret, "s hs traffic", transcript_hash);
501
502 // draft-thomson-tls-keylogfile-00 Section 3.1
503 // An implementation of TLS 1.3 use the label
504 // "CLIENT_HANDSHAKE_TRAFFIC_SECRET" and "SERVER_HANDSHAKE_TRAFFIC_SECRET"
505 // to identify the secrets are using to protect handshake messages.
506 loggger.maybe_log_secret("CLIENT_HANDSHAKE_TRAFFIC_SECRET", client_handshake_traffic_secret);
507 loggger.maybe_log_secret("SERVER_HANDSHAKE_TRAFFIC_SECRET", server_handshake_traffic_secret);
508
509 if(m_connection_side == Connection_Side::Server) {
510 derive_read_traffic_key(client_handshake_traffic_secret, true);
511 derive_write_traffic_key(server_handshake_traffic_secret, true);
512 } else {
513 derive_read_traffic_key(server_handshake_traffic_secret, true);
514 derive_write_traffic_key(client_handshake_traffic_secret, true);
515 }
516
517 m_salt = derive_secret(handshake_secret, "derived", empty_hash());
518
519 m_state = State::HandshakeTraffic;
520}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:41
static std::unique_ptr< AEAD_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition aead.cpp:43
bool is_compatible_with(const Ciphersuite &cipher) const

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Botan::TLS::Ciphersuite::cipher_algo(), Botan::AEAD_Mode::create_or_throw(), Botan::Decryption, Botan::Encryption, is_compatible_with(), Botan::TLS::Secret_Logger::maybe_log_secret(), and Botan::TLS::Server.

◆ can_decrypt_application_traffic()

bool Botan::TLS::Cipher_State::can_decrypt_application_traffic ( ) const

Indicates whether the appropriate secrets to decrypt application traffic are available

Definition at line 329 of file tls_cipher_state.cpp.

329 {
330 // TODO: when implementing early traffic (0-RTT) this will likely need
331 // to allow `State::EarlyTraffic`.
332
333 if(m_connection_side == Connection_Side::Client && m_state != State::ServerApplicationTraffic &&
334 m_state != State::Completed) {
335 return false;
336 }
337
338 if(m_connection_side == Connection_Side::Server && m_state != State::Completed) {
339 return false;
340 }
341
342 return !m_read_key.empty() && !m_read_iv.empty();
343}

References Botan::TLS::Client, and Botan::TLS::Server.

◆ can_encrypt_application_traffic()

bool Botan::TLS::Cipher_State::can_encrypt_application_traffic ( ) const

Indicates whether the appropriate secrets to encrypt application traffic are available

Definition at line 313 of file tls_cipher_state.cpp.

313 {
314 // TODO: when implementing early traffic (0-RTT) this will likely need
315 // to allow `State::EarlyTraffic`.
316
317 if(m_connection_side == Connection_Side::Client && m_state != State::Completed) {
318 return false;
319 }
320
321 if(m_connection_side == Connection_Side::Server && m_state != State::ServerApplicationTraffic &&
322 m_state != State::Completed) {
323 return false;
324 }
325
326 return !m_write_key.empty() && !m_write_iv.empty();
327}

References Botan::TLS::Client, and Botan::TLS::Server.

◆ can_export_keys()

bool Botan::TLS::Cipher_State::can_export_keys ( ) const
inline

Indicates whether the appropriate secrets to export keys are available

Definition at line 198 of file tls_cipher_state.h.

198 {
199 return (m_state == State::EarlyTraffic || m_state == State::ServerApplicationTraffic ||
200 m_state == State::Completed) &&
201 !m_exporter_master_secret.empty();
202 }

Referenced by export_key().

◆ clear_read_keys()

void Botan::TLS::Cipher_State::clear_read_keys ( )

Remove handshake/traffic secrets for decrypting data from peer

Definition at line 626 of file tls_cipher_state.cpp.

626 {
627 zap(m_read_key);
628 zap(m_read_iv);
629 zap(m_read_application_traffic_secret);
630}

References Botan::zap().

◆ clear_write_keys()

void Botan::TLS::Cipher_State::clear_write_keys ( )

Remove handshake/traffic secrets for encrypting data

Definition at line 632 of file tls_cipher_state.cpp.

632 {
633 zap(m_write_key);
634 zap(m_write_iv);
635 zap(m_write_application_traffic_secret);
636}

References Botan::zap().

◆ decrypt_output_length()

size_t Botan::TLS::Cipher_State::decrypt_output_length ( size_t input_length) const
Returns
number of bytes needed to decrypt input_length bytes

Definition at line 278 of file tls_cipher_state.cpp.

278 {
279 BOTAN_ASSERT_NONNULL(m_decrypt);
280 return m_decrypt->output_length(input_length);
281}
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::next_record().

◆ decrypt_record_fragment()

uint64_t Botan::TLS::Cipher_State::decrypt_record_fragment ( const std::vector< uint8_t > & header,
secure_vector< uint8_t > & encrypted_fragment )

Decrypt a TLS record fragment (RFC 8446 5.2 – TLSCiphertext.encrypted_record) using the currently available traffic secret keys and the current sequence number. This will internally increment the sequence number. Hence, multiple calls with the same input will not produce the same result.

Returns
the sequence number of the decrypted record

Definition at line 259 of file tls_cipher_state.cpp.

260 {
261 BOTAN_ASSERT_NONNULL(m_decrypt);
262 BOTAN_ARG_CHECK(encrypted_fragment.size() >= m_decrypt->minimum_final_size(), "fragment too short to decrypt");
263
264 m_decrypt->set_key(m_read_key);
265 m_decrypt->set_associated_data(header);
266 m_decrypt->start(current_nonce(m_read_seq_no, m_read_iv));
267
268 m_decrypt->finish(encrypted_fragment);
269
270 return m_read_seq_no++;
271}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29

References BOTAN_ARG_CHECK, and BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::next_record().

◆ encrypt_output_length()

size_t Botan::TLS::Cipher_State::encrypt_output_length ( size_t input_length) const
Returns
number of bytes needed to encrypt input_length bytes

Definition at line 273 of file tls_cipher_state.cpp.

273 {
274 BOTAN_ASSERT_NONNULL(m_encrypt);
275 return m_encrypt->output_length(input_length);
276}

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::prepare_records().

◆ encrypt_record_fragment()

uint64_t Botan::TLS::Cipher_State::encrypt_record_fragment ( const std::vector< uint8_t > & header,
secure_vector< uint8_t > & fragment )

Encrypt a TLS record fragment (RFC 8446 5.2 – TLSInnerPlaintext) using the currently available traffic secret keys and the current sequence number. This will internally increment the sequence number. Hence, multiple calls with the same input will not produce the same result.

Returns
the sequence number of the encrypted record

Definition at line 248 of file tls_cipher_state.cpp.

248 {
249 BOTAN_ASSERT_NONNULL(m_encrypt);
250
251 m_encrypt->set_key(m_write_key);
252 m_encrypt->set_associated_data(header);
253 m_encrypt->start(current_nonce(m_write_seq_no, m_write_iv));
254 m_encrypt->finish(fragment);
255
256 return m_write_seq_no++;
257}

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::prepare_records().

◆ export_key()

secure_vector< uint8_t > Botan::TLS::Cipher_State::export_key ( std::string_view label,
std::string_view context,
size_t length ) const

Derive key material to export (RFC 8446 7.5 and RFC 5705)

TODO: this does not yet support key export based on the early_exporter_master_secret.

RFC 8446 7.5 Implementations MUST use the exporter_master_secret unless explicitly specified by the application. The early_exporter_master_secret is defined for use in settings where an exporter is needed for 0-RTT data. A separate interface for the early exporter is RECOMMENDED [...].

Parameters
labela disambiguating label string
contexta per-association context value
lengththe length of the desired key in bytes
Returns
key of length bytes

Definition at line 422 of file tls_cipher_state.cpp.

422 {
424
425 m_hash->update(context);
426 const auto context_hash = m_hash->final_stdvec();
427 return hkdf_expand_label(
428 derive_secret(m_exporter_master_secret, label, empty_hash()), "exporter", context_hash, length);
429}

References BOTAN_ASSERT_NOMSG, and can_export_keys().

◆ finished_mac()

std::vector< uint8_t > Botan::TLS::Cipher_State::finished_mac ( const Transcript_Hash & transcript_hash) const

Calculate the MAC for a TLS "Finished" handshake message (RFC 8446 4.4.4)

Definition at line 381 of file tls_cipher_state.cpp.

381 {
382 BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Server || m_state == State::HandshakeTraffic);
383 BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Client || m_state == State::ServerApplicationTraffic);
384 BOTAN_ASSERT_NOMSG(!m_finished_key.empty());
385
386 auto hmac = HMAC(m_hash->new_object());
387 hmac.set_key(m_finished_key);
388 hmac.update(transcript_hash);
389 return hmac.final_stdvec();
390}

References BOTAN_ASSERT_NOMSG, Botan::TLS::Client, and Botan::TLS::Server.

Referenced by Botan::TLS::Finished_13::Finished_13().

◆ hash_algorithm()

std::string Botan::TLS::Cipher_State::hash_algorithm ( ) const

The name of the hash algorithm used for the KDF in this cipher suite

Definition at line 345 of file tls_cipher_state.cpp.

345 {
346 BOTAN_ASSERT_NONNULL(m_hash);
347 return m_hash->name();
348}

References BOTAN_ASSERT_NONNULL.

Referenced by is_compatible_with().

◆ init_with_psk()

std::unique_ptr< Cipher_State > Botan::TLS::Cipher_State::init_with_psk ( Connection_Side side,
const Cipher_State::PSK_Type type,
secure_vector< uint8_t > && psk,
std::string_view prf_algo )
static

Construct a Cipher_State from a Pre-Shared-Key.

Definition at line 132 of file tls_cipher_state.cpp.

135 {
136 auto cs = std::unique_ptr<Cipher_State>(new Cipher_State(side, prf_algo));
137 cs->advance_with_psk(type, std::move(psk));
138 return cs;
139}
secure_vector< uint8_t > psk(const Ticket_Nonce &nonce) const

References psk().

◆ init_with_server_hello()

std::unique_ptr< Cipher_State > Botan::TLS::Cipher_State::init_with_server_hello ( Connection_Side side,
secure_vector< uint8_t > && shared_secret,
const Ciphersuite & cipher,
const Transcript_Hash & transcript_hash,
const Secret_Logger & channel )
static

Construct a Cipher_State after receiving a server hello message.

Definition at line 121 of file tls_cipher_state.cpp.

125 {
126 auto cs = std::unique_ptr<Cipher_State>(new Cipher_State(side, cipher.prf_algo()));
127 cs->advance_without_psk();
128 cs->advance_with_server_hello(cipher, std::move(shared_secret), transcript_hash, loggger);
129 return cs;
130}

References Botan::TLS::Ciphersuite::prf_algo().

◆ is_compatible_with()

bool Botan::TLS::Cipher_State::is_compatible_with ( const Ciphersuite & cipher) const
Returns
true if the selected cipher primitives are compatible with the cipher suite.

Note that cipher suites are considered "compatible" as long as the already selected cipher primitives in this cipher state are compatible.

Definition at line 350 of file tls_cipher_state.cpp.

350 {
351 if(!cipher.usable_in_version(Protocol_Version::TLS_V13)) {
352 return false;
353 }
354
355 if(hash_algorithm() != cipher.prf_algo()) {
356 return false;
357 }
358
359 BOTAN_ASSERT_NOMSG((m_encrypt == nullptr) == (m_decrypt == nullptr));
360 // TODO: Find a better way to check that the instantiated cipher algorithm
361 // is compatible with the one required by the cipher suite.
362 // AEAD_Mode::create() sets defaults the tag length to 16 which is then
363 // reported via AEAD_Mode::name() and hinders the trivial string comparison.
364 if(m_encrypt && m_encrypt->name() != cipher.cipher_algo() && m_encrypt->name() != cipher.cipher_algo() + "(16)") {
365 return false;
366 }
367
368 return true;
369}
std::string hash_algorithm() const

References BOTAN_ASSERT_NOMSG, Botan::TLS::Ciphersuite::cipher_algo(), hash_algorithm(), Botan::TLS::Ciphersuite::prf_algo(), and Botan::TLS::Ciphersuite::usable_in_version().

Referenced by advance_with_server_hello().

◆ minimum_decryption_input_length()

size_t Botan::TLS::Cipher_State::minimum_decryption_input_length ( ) const
Returns
the minimum ciphertext length for decryption

Definition at line 283 of file tls_cipher_state.cpp.

283 {
284 BOTAN_ASSERT_NONNULL(m_decrypt);
285 return m_decrypt->minimum_final_size();
286}

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::next_record().

◆ must_expect_unprotected_alert_traffic()

bool Botan::TLS::Cipher_State::must_expect_unprotected_alert_traffic ( ) const

Indicates whether unprotected Alert records are to be expected

Definition at line 288 of file tls_cipher_state.cpp.

288 {
289 // Client side:
290 // After successfully receiving a Server Hello we expect servers to send
291 // alerts as protected records only, just like they start protecting their
292 // handshake data at this point.
293 if(m_connection_side == Connection_Side::Client && m_state == State::EarlyTraffic) {
294 return true;
295 }
296
297 // Server side:
298 // Servers must expect clients to send unprotected alerts during the hand-
299 // shake. In particular, in the response to the server's first protected
300 // flight. We don't expect the client to send alerts protected under the
301 // early traffic secret.
302 //
303 // TODO: when implementing PSK and/or early data for the server, we might
304 // need to reconsider this decision.
305 if(m_connection_side == Connection_Side::Server &&
306 (m_state == State::HandshakeTraffic || m_state == State::ServerApplicationTraffic)) {
307 return true;
308 }
309
310 return false;
311}

References Botan::TLS::Client, and Botan::TLS::Server.

Referenced by Botan::TLS::Record_Layer::next_record().

◆ next_ticket_nonce()

Ticket_Nonce Botan::TLS::Cipher_State::next_ticket_nonce ( )

Generates a nonce value that is unique for any given Cipher_State object. Note that the number of nonces is limited to 2^16 and this method will throw if more nonces are requested.

Definition at line 410 of file tls_cipher_state.cpp.

410 {
411 BOTAN_STATE_CHECK(m_state == State::Completed);
412 if(m_ticket_nonce == std::numeric_limits<decltype(m_ticket_nonce)>::max()) {
413 throw Botan::Invalid_State("ticket nonce pool exhausted");
414 }
415
416 Ticket_Nonce retval(std::vector<uint8_t>(sizeof(m_ticket_nonce)));
417 store_be(m_ticket_nonce++, retval.data());
418
419 return retval;
420}
Strong< std::vector< uint8_t >, struct Ticket_Nonce_ > Ticket_Nonce
Used to derive the ticket's PSK from the resumption_master_secret.
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:707

References BOTAN_STATE_CHECK, and Botan::store_be().

◆ psk()

secure_vector< uint8_t > Botan::TLS::Cipher_State::psk ( const Ticket_Nonce & nonce) const

Calculate the PSK for the given nonce (RFC 8446 4.6.1)

Definition at line 404 of file tls_cipher_state.cpp.

404 {
405 BOTAN_ASSERT_NOMSG(m_state == State::Completed);
406
407 return derive_secret(m_resumption_master_secret, "resumption", nonce.get());
408}

References BOTAN_ASSERT_NOMSG, and Botan::detail::Strong_Base< T >::get().

Referenced by init_with_psk().

◆ psk_binder_mac()

std::vector< uint8_t > Botan::TLS::Cipher_State::psk_binder_mac ( const Transcript_Hash & transcript_hash_with_truncated_client_hello) const

Calculates the MAC for a PSK binder value in Client Hellos. Note that the transcript hash passed into this method is computed from a partial Client Hello (RFC 8446 4.2.11.2)

Definition at line 371 of file tls_cipher_state.cpp.

372 {
373 BOTAN_ASSERT_NOMSG(m_state == State::PskBinder);
374
375 auto hmac = HMAC(m_hash->new_object());
376 hmac.set_key(m_binder_key);
377 hmac.update(transcript_hash_with_truncated_client_hello);
378 return hmac.final_stdvec();
379}

References BOTAN_ASSERT_NOMSG.

◆ update_read_keys()

void Botan::TLS::Cipher_State::update_read_keys ( const Secret_Logger & channel)

Updates the key material used for decrypting data This is triggered after we received a Key_Update from the peer.

Note that this must not be called before the connection is ready for application traffic.

Definition at line 599 of file tls_cipher_state.cpp.

599 {
600 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
601
602 m_read_application_traffic_secret =
603 hkdf_expand_label(m_read_application_traffic_secret, "traffic upd", {}, m_hash->output_length());
604
605 const auto secret_label = fmt("{}_TRAFFIC_SECRET_{}",
606 m_connection_side == Connection_Side::Server ? "CLIENT" : "SERVER",
607 ++m_read_key_update_count);
608 logger.maybe_log_secret(secret_label, m_read_application_traffic_secret);
609
610 derive_read_traffic_key(m_read_application_traffic_secret);
611}
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53

References BOTAN_ASSERT_NOMSG, Botan::fmt(), Botan::TLS::Secret_Logger::maybe_log_secret(), and Botan::TLS::Server.

◆ update_write_keys()

void Botan::TLS::Cipher_State::update_write_keys ( const Secret_Logger & channel)

Updates the key material used for encrypting data This is triggered after we send a Key_Update to the peer.

Note that this must not be called before the connection is ready for application traffic.

Definition at line 613 of file tls_cipher_state.cpp.

613 {
614 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
615 m_write_application_traffic_secret =
616 hkdf_expand_label(m_write_application_traffic_secret, "traffic upd", {}, m_hash->output_length());
617
618 const auto secret_label = fmt("{}_TRAFFIC_SECRET_{}",
619 m_connection_side == Connection_Side::Server ? "SERVER" : "CLIENT",
620 ++m_write_key_update_count);
621 logger.maybe_log_secret(secret_label, m_write_application_traffic_secret);
622
623 derive_write_traffic_key(m_write_application_traffic_secret);
624}

References BOTAN_ASSERT_NOMSG, Botan::fmt(), Botan::TLS::Secret_Logger::maybe_log_secret(), and Botan::TLS::Server.

◆ verify_peer_finished_mac()

bool Botan::TLS::Cipher_State::verify_peer_finished_mac ( const Transcript_Hash & transcript_hash,
const std::vector< uint8_t > & peer_mac ) const

Validate a MAC received in a TLS "Finished" handshake message (RFC 8446 4.4.4)

Definition at line 392 of file tls_cipher_state.cpp.

393 {
394 BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Server || m_state == State::ServerApplicationTraffic);
395 BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Client || m_state == State::HandshakeTraffic);
396 BOTAN_ASSERT_NOMSG(!m_peer_finished_key.empty());
397
398 auto hmac = HMAC(m_hash->new_object());
399 hmac.set_key(m_peer_finished_key);
400 hmac.update(transcript_hash);
401 return hmac.verify_mac(peer_mac);
402}

References BOTAN_ASSERT_NOMSG, Botan::TLS::Client, and Botan::TLS::Server.

Referenced by Botan::TLS::Finished_13::verify().


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