Botan 3.11.0
Crypto and TLS for C&
tls_server_impl_13.cpp
Go to the documentation of this file.
1/*
2* TLS Server - implementation for TLS 1.3
3* (C) 2022 Jack Lloyd
4* 2022 René Meusel - Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/internal/tls_server_impl_13.h>
10
11#include <botan/credentials_manager.h>
12#include <botan/rng.h>
13#include <botan/tls_callbacks.h>
14#include <botan/tls_extensions_13.h>
15#include <botan/tls_policy.h>
16#include <botan/x509cert.h>
17#include <botan/internal/stl_util.h>
18#include <botan/internal/tls_cipher_state.h>
19
20namespace Botan::TLS {
21
22Server_Impl_13::Server_Impl_13(const std::shared_ptr<Callbacks>& callbacks,
23 const std::shared_ptr<Session_Manager>& session_manager,
24 const std::shared_ptr<Credentials_Manager>& credentials_manager,
25 const std::shared_ptr<const Policy>& policy,
26 const std::shared_ptr<RandomNumberGenerator>& rng) :
28#if defined(BOTAN_HAS_TLS_12)
29 if(policy->allow_tls12()) {
30 expect_downgrade({}, {});
31 }
32#endif
33
34 m_transitions.set_expected_next(Handshake_Type::ClientHello);
35}
36
39 const auto& eee = m_handshake_state.encrypted_extensions().extensions();
40 if(auto* const alpn = eee.get<Application_Layer_Protocol_Notification>()) {
41 return alpn->single_protocol();
42 }
43 }
44
45 return "";
46}
47
48std::vector<X509_Certificate> Server_Impl_13::peer_cert_chain() const {
49 if(m_handshake_state.has_client_certificate_msg() &&
50 m_handshake_state.client_certificate().has_certificate_chain()) {
51 return m_handshake_state.client_certificate().cert_chain();
52 }
53
54 if(m_resumed_session.has_value()) {
55 return m_resumed_session->peer_certs();
56 }
57
58 return {};
59}
60
61std::shared_ptr<const Public_Key> Server_Impl_13::peer_raw_public_key() const {
62 if(m_handshake_state.has_client_certificate_msg() && m_handshake_state.client_certificate().is_raw_public_key()) {
63 return m_handshake_state.client_certificate().public_key();
64 }
65
66 if(m_resumed_session.has_value()) {
67 return m_resumed_session->peer_raw_public_key();
68 }
69
70 return nullptr;
71}
72
73std::optional<std::string> Server_Impl_13::external_psk_identity() const {
74 return m_psk_identity;
75}
76
78 // RFC 8446 4.2.9
79 // This extension also restricts the modes for use with PSK resumption.
80 // Servers SHOULD NOT send NewSessionTicket with tickets that are not
81 // compatible with the advertised modes; however, if a server does so,
82 // the impact will just be that the client's attempts at resumption fail.
83 //
84 // Note: Applications can overrule this by calling send_new_session_tickets()
85 // regardless of this method indicating no support for tickets.
86 //
87 // TODO: Implement other PSK KE modes than PSK_DHE_KE
88 return is_handshake_complete() && m_handshake_state.client_hello().extensions().has<PSK_Key_Exchange_Modes>() &&
89 value_exists(m_handshake_state.client_hello().extensions().get<PSK_Key_Exchange_Modes>()->modes(),
91}
92
93size_t Server_Impl_13::send_new_session_tickets(const size_t tickets) {
95
96 if(tickets == 0) {
97 return 0;
98 }
99
100 auto flight = aggregate_post_handshake_messages();
101 size_t tickets_created = 0;
102
103 for(size_t i = 0; i < tickets; ++i) {
104 auto nonce = m_cipher_state->next_ticket_nonce();
105 const Session session(m_cipher_state->psk(nonce),
106 std::nullopt, // early data not yet implemented
107 policy().session_ticket_lifetime(),
110 m_handshake_state.client_hello(),
111 m_handshake_state.server_hello(),
112 callbacks(),
113 rng());
114
115 if(callbacks().tls_should_persist_resumption_information(session)) {
116 if(auto handle = session_manager().establish(session)) {
117 flight.add(New_Session_Ticket_13(std::move(nonce), session, handle.value(), callbacks()));
118 ++tickets_created;
119 }
120 }
121 }
122
123 if(flight.contains_messages()) {
124 flight.send();
125 }
126
127 return tickets_created;
128}
129
130void Server_Impl_13::process_handshake_msg(Handshake_Message_13 message) {
131 std::visit(
132 [&](auto msg) {
133 // first verify that the message was expected by the state machine...
134 m_transitions.confirm_transition_to(msg.get().type());
135
136 // ... then allow the library user to abort on their discretion
137 callbacks().tls_inspect_handshake_msg(msg.get());
138
139 // ... finally handle the message
140 handle(msg.get());
141 },
142 m_handshake_state.received(std::move(message)));
143}
144
145void Server_Impl_13::process_post_handshake_msg(Post_Handshake_Message_13 message) {
146 BOTAN_STATE_CHECK(is_handshake_complete());
147
148 std::visit([&](auto msg) { handle(msg); }, m_handshake_state.received(std::move(message)));
149}
150
151void Server_Impl_13::process_dummy_change_cipher_spec() {
152 // RFC 8446 5.
153 // If an implementation detects a change_cipher_spec record received before
154 // the first ClientHello message or after the peer's Finished message, it MUST be
155 // treated as an unexpected record type [("unexpected_message" alert)].
156 if(!m_handshake_state.has_client_hello() || m_handshake_state.has_client_finished()) {
157 throw TLS_Exception(Alert::UnexpectedMessage, "Received an unexpected dummy Change Cipher Spec");
158 }
159
160 // RFC 8446 5.
161 // An implementation may receive an unencrypted record of type change_cipher_spec [...]
162 // at any time after the first ClientHello message has been sent or received
163 // and before the peer's Finished message has been received [...]
164 // and MUST simply drop it without further processing.
165 //
166 // ... no further processing.
167}
168
170 return m_handshake_state.handshake_finished();
171}
172
173void Server_Impl_13::maybe_log_secret(std::string_view label, std::span<const uint8_t> secret) const {
174 if(policy().allow_ssl_key_log_file()) {
175 callbacks().tls_ssl_key_log_data(label, m_handshake_state.client_hello().random(), secret);
176 }
177}
178
179void Server_Impl_13::downgrade() {
180 BOTAN_ASSERT_NOMSG(expects_downgrade());
181
182 request_downgrade();
183
184 // After this, no further messages are expected here because this instance
185 // will be replaced by a Server_Impl_12.
186 m_transitions.set_expected_next({});
187}
188
189void Server_Impl_13::maybe_handle_compatibility_mode() {
190 BOTAN_ASSERT_NOMSG(m_handshake_state.has_client_hello());
191 BOTAN_ASSERT_NOMSG(m_handshake_state.has_hello_retry_request() || m_handshake_state.has_server_hello());
192
193 // RFC 8446 Appendix D.4 (Middlebox Compatibility Mode)
194 // The server sends a dummy change_cipher_spec record immediately after
195 // its first handshake message. This may either be after a ServerHello or
196 // a HelloRetryRequest.
197 //
198 // This "compatibility mode" is partially negotiated: the client can opt
199 // to provide a session ID or not, and the server has to echo it. Either
200 // side can send change_cipher_spec at any time during the handshake, as
201 // they must be ignored by the peer, but if the client sends a non-empty
202 // session ID, the server MUST send the change_cipher_spec as described
203 // [above].
204 //
205 // Technically, the usage of compatibility mode is fully up to the client
206 // sending a non-empty session ID. Nevertheless, when the policy requests
207 // it we send a CCS regardless. Note that this is perfectly legal and also
208 // satisfies some BoGo tests that expect this behaviour.
209 //
210 // Send a CCS immediately after the _first_ handshake message. I.e. either
211 // after Hello Retry Request (exclusively) or after a Server Hello that was
212 // not preseded by a Hello Retry Request.
213 const bool just_after_first_handshake_message =
214 m_handshake_state.has_hello_retry_request() ^ m_handshake_state.has_server_hello();
215 const bool client_requested_compatibility_mode = !m_handshake_state.client_hello().session_id().empty();
216
217 if(just_after_first_handshake_message &&
218 (policy().tls_13_middlebox_compatibility_mode() || client_requested_compatibility_mode)) {
219 send_dummy_change_cipher_spec();
220 }
221}
222
223void Server_Impl_13::handle_reply_to_client_hello(Server_Hello_13 server_hello) {
224 const auto& client_hello = m_handshake_state.client_hello();
225 const auto& exts = client_hello.extensions();
226
227 const bool uses_psk = server_hello.extensions().has<PSK>();
228
229 const auto cipher_opt = Ciphersuite::by_id(server_hello.ciphersuite());
230 BOTAN_ASSERT_NOMSG(cipher_opt.has_value());
231 const auto& cipher = cipher_opt.value();
232 m_transcript_hash.set_algorithm(cipher.prf_algo());
233
234 std::unique_ptr<Cipher_State> psk_cipher_state;
235 if(uses_psk) {
236 auto* psk_extension = server_hello.extensions().get<PSK>();
237
238 psk_cipher_state =
239 std::visit(overloaded{[&, this](Session session) {
240 m_resumed_session = std::move(session);
241 return Cipher_State::init_with_psk(Connection_Side::Server,
242 Cipher_State::PSK_Type::Resumption,
243 m_resumed_session->extract_master_secret(),
244 cipher.prf_algo());
245 },
246 [&, this](ExternalPSK psk) {
247 m_psk_identity = psk.identity();
248 return Cipher_State::init_with_psk(Connection_Side::Server,
249 Cipher_State::PSK_Type::External,
250 psk.extract_master_secret(),
251 cipher.prf_algo());
252 }},
253 psk_extension->take_session_to_resume_or_psk());
254
255 // RFC 8446 4.2.11
256 // Prior to accepting PSK key establishment, the server MUST validate
257 // the corresponding binder value (see Section 4.2.11.2 below). If this
258 // value is not present or does not validate, the server MUST abort the
259 // handshake.
260 // Servers SHOULD NOT attempt to validate multiple binders; rather,
261 // they SHOULD select a single PSK and validate solely the binder that
262 // corresponds to that PSK.
263 //
264 // Note: PSK selection was performed earlier, resulting in the existence
265 // of this extension in the first place.
266 if(!exts.get<PSK>()->validate_binder(*psk_extension,
267 psk_cipher_state->psk_binder_mac(m_transcript_hash.truncated()))) {
268 throw TLS_Exception(Alert::DecryptError, "PSK binder does not check out");
269 }
270
271 // RFC 8446 4.2.10
272 // For PSKs provisioned via NewSessionTicket, a server MUST validate
273 // that the ticket age for the selected PSK identity [...] is within a
274 // small tolerance of the time since the ticket was issued. If it is
275 // not, the server SHOULD proceed with the handshake but reject 0-RTT,
276 // and SHOULD NOT take any other action that assumes that this
277 // ClientHello is fresh.
278 //
279 // TODO: When implementing Early Data (0-RTT) we should take the above
280 // paragraph into account. Note that there are BoGo tests that
281 // validate this behaviour. Namely: TLS13-TicketAgeSkew-*
282 }
283
284 // This sends the server_hello to the peer.
285 // NOTE: the server_hello variable is moved into the handshake state. Later
286 // references to the Server Hello will need to consult the handshake
287 // state object!
288 send_handshake_message(m_handshake_state.sending(std::move(server_hello)));
289 maybe_handle_compatibility_mode();
290
291 // Setup encryption for all the remaining handshake messages
292 m_cipher_state = [&] {
293 // Currently, PSK without DHE is not implemented...
294 auto* const my_keyshare = m_handshake_state.server_hello().extensions().get<Key_Share>();
295 BOTAN_ASSERT_NONNULL(my_keyshare);
296
297 if(uses_psk) {
298 BOTAN_ASSERT_NONNULL(psk_cipher_state);
299 psk_cipher_state->advance_with_client_hello(m_transcript_hash.previous(), *this);
300 psk_cipher_state->advance_with_server_hello(
301 cipher, my_keyshare->take_shared_secret(), m_transcript_hash.current(), *this);
302
303 return std::move(psk_cipher_state);
304 } else {
305 return Cipher_State::init_with_server_hello(
306 m_side, my_keyshare->take_shared_secret(), cipher, m_transcript_hash.current(), *this);
307 }
308 }();
309
310 auto flight = aggregate_handshake_messages();
311 flight.add(m_handshake_state.sending(Encrypted_Extensions(client_hello, policy(), callbacks())));
312
313 if(!uses_psk) {
314 // RFC 8446 4.3.2
315 // A server which is authenticating with a certificate MAY optionally
316 // request a certificate from the client. This message, if sent, MUST
317 // follow EncryptedExtensions.
318 if(auto certificate_request =
319 Certificate_Request_13::maybe_create(client_hello, credentials_manager(), callbacks(), policy())) {
320 flight.add(m_handshake_state.sending(std::move(certificate_request.value())));
321 }
322
323 const auto& enc_exts = m_handshake_state.encrypted_extensions().extensions();
324
325 // RFC 7250 4.2
326 // This client_certificate_type extension in the server hello then
327 // indicates the type of certificates the client is requested to provide
328 // in a subsequent certificate payload.
329 //
330 // Note: TLS 1.3 carries this extension in the Encrypted Extensions
331 // message instead of the Server Hello.
332 if(auto* client_cert_type = enc_exts.get<Client_Certificate_Type>()) {
333 set_selected_certificate_type(client_cert_type->selected_certificate_type());
334 }
335
336 // RFC 8446 4.4.2
337 // If the corresponding certificate type extension [...] was not
338 // negotiated in EncryptedExtensions, or the X.509 certificate type
339 // was negotiated, then each CertificateEntry contains a DER-encoded
340 // X.509 certificate.
341 const auto cert_type = [&] {
342 if(auto* server_cert_type = enc_exts.get<Server_Certificate_Type>()) {
343 return server_cert_type->selected_certificate_type();
344 } else {
345 return Certificate_Type::X509;
346 }
347 }();
348
349 flight.add(m_handshake_state.sending(Certificate_13(client_hello, credentials_manager(), callbacks(), cert_type)))
350 .add(m_handshake_state.sending(Certificate_Verify_13(m_handshake_state.server_certificate(),
351 client_hello.signature_schemes(),
352 client_hello.sni_hostname(),
353 m_transcript_hash.current(),
354 Connection_Side::Server,
355 credentials_manager(),
356 policy(),
357 callbacks(),
358 rng())));
359 }
360
361 flight.add(m_handshake_state.sending(Finished_13(m_cipher_state.get(), m_transcript_hash.current())));
362
363 if(client_hello.extensions().has<Record_Size_Limit>() &&
364 m_handshake_state.encrypted_extensions().extensions().has<Record_Size_Limit>()) {
365 // RFC 8449 4.
366 // When the "record_size_limit" extension is negotiated, an endpoint
367 // MUST NOT generate a protected record with plaintext that is larger
368 // than the RecordSizeLimit value it receives from its peer.
369 // Unprotected messages are not subject to this limit.
370 //
371 // Hence, the limit is set just before we start sending encrypted records.
372 //
373 // RFC 8449 4.
374 // The record size limit only applies to records sent toward the
375 // endpoint that advertises the limit. An endpoint can send records
376 // that are larger than the limit it advertises as its own limit.
377 //
378 // Hence, the "outgoing" limit is what the client requested and the
379 // "incoming" limit is what we will request in the Encrypted Extensions.
380 auto* const outgoing_limit = client_hello.extensions().get<Record_Size_Limit>();
381 auto* const incoming_limit = m_handshake_state.encrypted_extensions().extensions().get<Record_Size_Limit>();
382 set_record_size_limits(outgoing_limit->limit(), incoming_limit->limit());
383 }
384
385 flight.send();
386
387 m_cipher_state->advance_with_server_finished(m_transcript_hash.current(), *this);
388
389 if(m_handshake_state.has_certificate_request()) {
390 // RFC 8446 4.4.2
391 // The client MUST send a Certificate message if and only if the server
392 // has requested client authentication via a CertificateRequest message
393 // [...]. If the server requests client authentication but no
394 // suitable certificate is available, the client MUST send a Certificate
395 // message containing no certificates [...].
396 m_transitions.set_expected_next(Handshake_Type::Certificate);
397 } else {
398 m_transitions.set_expected_next(Handshake_Type::Finished);
399 }
400}
401
402void Server_Impl_13::handle_reply_to_client_hello(Hello_Retry_Request hello_retry_request) {
403 auto cipher = Ciphersuite::by_id(hello_retry_request.ciphersuite());
404 BOTAN_ASSERT_NOMSG(cipher.has_value()); // should work, since we chose that suite
405
406 send_handshake_message(m_handshake_state.sending(std::move(hello_retry_request)));
407 maybe_handle_compatibility_mode();
408
409 m_transcript_hash = Transcript_Hash_State::recreate_after_hello_retry_request(cipher->prf_algo(), m_transcript_hash);
410
411 m_transitions.set_expected_next(Handshake_Type::ClientHello);
412}
413
414void Server_Impl_13::handle(const Client_Hello_12_Shim& ch) {
415 // The detailed handling of the TLS 1.2 compliant Client Hello is left to
416 // the TLS 1.2 server implementation.
417 BOTAN_UNUSED(ch);
418
419 // After we sent a Hello Retry Request we must not accept a downgrade.
420 if(m_handshake_state.has_hello_retry_request()) {
421 throw TLS_Exception(Alert::UnexpectedMessage, "Received a TLS 1.2 Client Hello after Hello Retry Request");
422 }
423
424 // RFC 8446 Appendix D.2
425 // If the "supported_versions" extension is absent and the server only
426 // supports versions greater than ClientHello.legacy_version, the server
427 // MUST abort the handshake with a "protocol_version" alert.
428 //
429 // If we're not expecting a downgrade, we only support TLS 1.3.
430 if(!expects_downgrade()) {
431 throw TLS_Exception(Alert::ProtocolVersion, "Received a legacy Client Hello");
432 }
433
434 downgrade();
435}
436
437void Server_Impl_13::handle(const Client_Hello_13& client_hello) {
438 const auto& exts = client_hello.extensions();
439
440 const bool is_initial_client_hello = !m_handshake_state.has_hello_retry_request();
441
442 if(is_initial_client_hello) {
443 const auto preferred_version = client_hello.highest_supported_version(policy());
444 if(!preferred_version) {
445 throw TLS_Exception(Alert::ProtocolVersion, "No shared TLS version");
446 }
447
448 // RFC 8446 4.2.2
449 // Clients MUST NOT use cookies in their initial ClientHello in subsequent
450 // connections.
451 if(exts.has<Cookie>()) {
452 throw TLS_Exception(Alert::IllegalParameter, "Received a Cookie in the initial client hello");
453 }
454 }
455
456 // TODO: Implement support for PSK. For now, we ignore any such extensions
457 // and always revert to a standard key exchange.
458 if(!exts.has<Supported_Groups>()) {
459 throw Not_Implemented("PSK-only handshake NYI");
460 }
461
462 // RFC 8446 9.2
463 // If containing a "supported_groups" extension, [Client Hello] MUST
464 // also contain a "key_share" extension, and vice versa.
465 //
466 // This was validated before in the Client_Hello_13 constructor.
467 BOTAN_ASSERT_NOMSG(exts.has<Key_Share>());
468
469 if(!is_initial_client_hello) {
470 const auto& hrr_exts = m_handshake_state.hello_retry_request().extensions();
471 const auto offered_groups = exts.get<Key_Share>()->offered_groups();
472 const auto selected_group = hrr_exts.get<Key_Share>()->selected_group();
473 if(offered_groups.size() != 1 || offered_groups.at(0) != selected_group) {
474 throw TLS_Exception(Alert::IllegalParameter, "Client did not comply with the requested key exchange group");
475 }
476 }
477
478 callbacks().tls_examine_extensions(exts, Connection_Side::Client, client_hello.type());
479 std::visit([this](auto msg) { handle_reply_to_client_hello(std::move(msg)); },
480 Server_Hello_13::create(client_hello,
481 is_initial_client_hello,
482 session_manager(),
483 credentials_manager(),
484 rng(),
485 policy(),
486 callbacks()));
487}
488
489void Server_Impl_13::handle(const Certificate_13& certificate_msg) {
490 // RFC 8446 4.3.2
491 // certificate_request_context: [...] This field SHALL be zero length
492 // unless used for the post-handshake authentication exchanges [...].
493 if(!is_handshake_complete() && !certificate_msg.request_context().empty()) {
494 throw TLS_Exception(Alert::DecodeError, "Received a client certificate message with non-empty request context");
495 }
496
497 // RFC 8446 4.4.2
498 // Extensions in the Certificate message from the client MUST correspond
499 // to extensions in the CertificateRequest message from the server.
500 certificate_msg.validate_extensions(m_handshake_state.certificate_request().extensions().extension_types(),
501 callbacks());
502
503 // RFC 8446 4.4.2.4
504 // If the client does not send any certificates (i.e., it sends an empty
505 // Certificate message), the server MAY at its discretion either continue
506 // the handshake without client authentication or abort the handshake with
507 // a "certificate_required" alert.
508 if(certificate_msg.empty()) {
509 if(policy().require_client_certificate_authentication()) {
510 throw TLS_Exception(Alert::CertificateRequired, "Policy requires client send a certificate, but it did not");
511 }
512
513 // RFC 8446 4.4.2
514 // A Finished message MUST be sent regardless of whether the
515 // Certificate message is empty.
516 m_transitions.set_expected_next(Handshake_Type::Finished);
517 } else {
518 // RFC 8446 4.4.2.4
519 // [...], if some aspect of the certificate chain was unacceptable
520 // (e.g., it was not signed by a known, trusted CA), the server MAY at
521 // its discretion either continue the handshake (considering the client
522 // unauthenticated) or abort the handshake.
523 //
524 // TODO: We could make this dependent on Policy::require_client_auth().
525 // Though, apps may also override Callbacks::tls_verify_cert_chain()
526 // and 'ignore' validation issues to a certain extent.
527 certificate_msg.verify(callbacks(),
528 policy(),
529 credentials_manager(),
530 m_handshake_state.client_hello().sni_hostname(),
531 m_handshake_state.client_hello().extensions().has<Certificate_Status_Request>());
532
533 // RFC 8446 4.4.3
534 // Clients MUST send this message whenever authenticating via a
535 // certificate (i.e., when the Certificate message
536 // is non-empty). When sent, this message MUST appear immediately after
537 // the Certificate message [...].
538 m_transitions.set_expected_next(Handshake_Type::CertificateVerify);
539 }
540}
541
542void Server_Impl_13::handle(const Certificate_Verify_13& certificate_verify_msg) {
543 // RFC 8446 4.4.3
544 // If sent by a client, the signature algorithm used in the signature
545 // MUST be one of those present in the supported_signature_algorithms
546 // field of the "signature_algorithms" extension in the
547 // CertificateRequest message.
548 const auto offered = m_handshake_state.certificate_request().signature_schemes();
549 if(!value_exists(offered, certificate_verify_msg.signature_scheme())) {
550 throw TLS_Exception(Alert::IllegalParameter,
551 "We did not offer the usage of " + certificate_verify_msg.signature_scheme().to_string() +
552 " as a signature scheme");
553 }
554
555 BOTAN_ASSERT_NOMSG(m_handshake_state.has_client_certificate_msg() &&
556 !m_handshake_state.client_certificate().empty());
557 const bool sig_valid = certificate_verify_msg.verify(
558 *m_handshake_state.client_certificate().public_key(), callbacks(), m_transcript_hash.previous());
559
560 // RFC 8446 4.4.3
561 // If the verification fails, the receiver MUST terminate the handshake
562 // with a "decrypt_error" alert.
563 if(!sig_valid) {
564 throw TLS_Exception(Alert::DecryptError, "Client certificate verification failed");
565 }
566
567 m_transitions.set_expected_next(Handshake_Type::Finished);
568}
569
570void Server_Impl_13::handle(const Finished_13& finished_msg) {
571 // RFC 8446 4.4.4
572 // Recipients of Finished messages MUST verify that the contents are
573 // correct and if incorrect MUST terminate the connection with a
574 // "decrypt_error" alert.
575 if(!finished_msg.verify(m_cipher_state.get(), m_transcript_hash.previous())) {
576 throw TLS_Exception(Alert::DecryptError, "Finished message didn't verify");
577 }
578
579 // Give the application a chance for a final veto before fully
580 // establishing the connection.
581 callbacks().tls_session_established(
582 Session_Summary(m_handshake_state.server_hello(),
583 Connection_Side::Server,
584 peer_cert_chain(),
585 peer_raw_public_key(),
586 m_psk_identity,
587 m_resumed_session.has_value(),
588 Server_Information(m_handshake_state.client_hello().sni_hostname()),
589 callbacks().tls_current_timestamp()));
590
591 m_cipher_state->advance_with_client_finished(m_transcript_hash.current());
592
593 // no more handshake messages expected
594 m_transitions.set_expected_next({});
595
596 callbacks().tls_session_activated();
597
598 if(new_session_ticket_supported()) {
599 send_new_session_tickets(policy().new_session_tickets_upon_handshake_success());
600 }
601}
602
603} // namespace Botan::TLS
#define BOTAN_UNUSED
Definition assert.h:144
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
const Policy & policy() const
AggregatedPostHandshakeMessages aggregate_post_handshake_messages()
Credentials_Manager & credentials_manager()
RandomNumberGenerator & rng()
Channel_Impl_13(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< RandomNumberGenerator > &rng, const std::shared_ptr< const Policy > &policy, bool is_server)
Session_Manager & session_manager()
std::unique_ptr< Cipher_State > m_cipher_state
const std::vector< PSK_Key_Exchange_Mode > & modes() const
std::vector< X509_Certificate > peer_cert_chain() const override
size_t send_new_session_tickets(size_t tickets) override
std::optional< std::string > external_psk_identity() const override
std::shared_ptr< const Public_Key > peer_raw_public_key() const override
bool is_handshake_complete() const override
std::string application_protocol() const override
bool new_session_ticket_supported() const override
Server_Impl_13(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< const Policy > &policy, const std::shared_ptr< RandomNumberGenerator > &rng)
std::variant< Client_Hello_13, Client_Hello_12_Shim, Server_Hello_13, Server_Hello_12_Shim, Hello_Retry_Request, Encrypted_Extensions, Certificate_13, Certificate_Request_13, Certificate_Verify_13, Finished_13 > Handshake_Message_13
bool value_exists(const std::vector< T > &vec, const V &val)
Definition stl_util.h:43