9#include <botan/internal/tls_server_impl_13.h>
11#include <botan/credentials_manager.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/loadstor.h>
18#include <botan/internal/stl_util.h>
19#include <botan/internal/tls_cipher_state.h>
26 const std::shared_ptr<const Policy>&
policy,
27 const std::shared_ptr<RandomNumberGenerator>&
rng) :
29 m_handshake(std::make_unique<Pending_Handshake>()) {
30#if defined(BOTAN_HAS_TLS_12)
31 if(
policy->allow_tls12()) {
32 expect_downgrade({}, {});
53 if(m_handshake->state.has_client_certificate_msg() &&
54 m_handshake->state.client_certificate().has_certificate_chain()) {
55 return m_handshake->state.client_certificate().cert_chain();
58 if(m_handshake->resumed_session.has_value()) {
59 return m_handshake->resumed_session->peer_certs();
72 if(m_handshake->state.has_client_certificate_msg() &&
73 m_handshake->state.client_certificate().is_raw_public_key()) {
74 return m_handshake->state.client_certificate().public_key();
77 if(m_handshake->resumed_session.has_value()) {
78 return m_handshake->resumed_session->peer_raw_public_key();
88 }
else if(m_handshake) {
89 return m_handshake->psk_identity;
118 size_t tickets_created = 0;
122 for(
size_t i = 0; i < tickets; ++i) {
124 const uint32_t ticket_age_add =
load_be(
rng().random_array<4>());
128 policy().session_ticket_lifetime(),
137 if(
callbacks().tls_should_persist_resumption_information(session)) {
145 if(flight.contains_messages()) {
149 return tickets_created;
157 m_handshake->transitions.confirm_transition_to(std::visit([](
const auto& msg) {
return msg.type(); }, message));
162 callbacks().tls_inspect_handshake_msg(msg.get());
167 m_handshake->state.received(std::move(message)));
170void Server_Impl_13::process_post_handshake_msg(Post_Handshake_Message_13 message) {
175 throw TLS_Exception(Alert::UnexpectedMessage,
"Received an unexpected post-handshake message");
178 std::visit([&](
auto&& m) { handle(m); }, *msg);
181void Server_Impl_13::process_dummy_change_cipher_spec() {
186 if(!m_handshake || !m_handshake->state.has_client_hello() || m_handshake->state.has_client_finished()) {
187 throw TLS_Exception(Alert::UnexpectedMessage,
"Received an unexpected dummy Change Cipher Spec");
200 return m_active_state.has_value() || (m_handshake !=
nullptr && m_handshake->state.handshake_finished());
203void Server_Impl_13::maybe_log_secret(std::string_view label, std::span<const uint8_t> secret)
const {
204 if(policy().allow_ssl_key_log_file()) {
205 if(m_active_state.has_value()) {
206 callbacks().tls_ssl_key_log_data(label, m_active_state->client_random(), secret);
208 callbacks().tls_ssl_key_log_data(label, m_handshake->state.client_hello().random(), secret);
213#if defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
215void Server_Impl_13::downgrade() {
222 m_handshake->transitions.set_expected_next({});
227void Server_Impl_13::maybe_handle_compatibility_mode(Compat_Mode_Situation situation) {
234 if(m_handshake ==
nullptr || !m_handshake->state.has_client_hello()) {
250 const bool client_requested_compatibility_mode = !m_handshake->state.client_hello().session_id().empty();
251 if(!policy().tls_13_middlebox_compatibility_mode() && !client_requested_compatibility_mode) {
256 case Compat_Mode_Situation::AfterSendingFirstServerHello:
257 case Compat_Mode_Situation::AfterSendingHelloRetryRequest:
262 send_dummy_change_cipher_spec();
265 case Compat_Mode_Situation::BeforeSendingAlert:
274 case Compat_Mode_Situation::AfterSendingFirstClientHello:
275 case Compat_Mode_Situation::BeforeSendingSecondClientHello:
276 case Compat_Mode_Situation::BeforeSendingEncryptedClientFlight:
281void Server_Impl_13::handle_reply_to_client_hello(Server_Hello_13 server_hello) {
282 const auto& client_hello = m_handshake->state.client_hello();
283 const auto& exts = client_hello.extensions();
285 const bool uses_psk = server_hello.extensions().has<
PSK>();
287 const auto cipher_opt = Ciphersuite::by_id(server_hello.ciphersuite());
289 const auto& cipher = cipher_opt.value();
290 m_transcript_hash.set_algorithm(cipher.prf_algo());
292 std::unique_ptr<Cipher_State> psk_cipher_state;
294 auto* psk_extension = server_hello.extensions().get<
PSK>();
296 psk_cipher_state = std::visit(
298 m_handshake->resumed_session = std::move(session);
299 return Cipher_State::init_with_psk(Connection_Side::Server,
300 Cipher_State::PSK_Type::Resumption,
301 m_handshake->resumed_session->extract_master_secret(),
304 [&,
this](ExternalPSK psk) {
305 m_handshake->psk_identity = psk.identity();
306 const auto psk_type =
307 psk.is_imported() ? Cipher_State::PSK_Type::Imported : Cipher_State::PSK_Type::External;
308 return Cipher_State::init_with_psk(
309 Connection_Side::Server, psk_type, psk.extract_master_secret(), cipher.prf_algo());
311 psk_extension->take_session_to_resume_or_psk());
324 if(!exts.get<PSK>()->validate_binder(*psk_extension,
325 psk_cipher_state->psk_binder_mac(m_transcript_hash.truncated()))) {
326 throw TLS_Exception(Alert::DecryptError,
"PSK binder does not check out");
346 send_handshake_message(m_handshake->state.sending(std::move(server_hello)));
348 if(!m_handshake->state.has_hello_retry_request()) {
349 maybe_handle_compatibility_mode(Compat_Mode_Situation::AfterSendingFirstServerHello);
353 m_cipher_state = [&] {
355 auto*
const my_keyshare = m_handshake->state.server_hello().extensions().get<Key_Share>();
360 psk_cipher_state->advance_with_client_hello(m_transcript_hash.previous(), *
this);
361 psk_cipher_state->advance_with_server_hello(
362 cipher, my_keyshare->take_shared_secret(), m_transcript_hash.current(), *
this);
364 return std::move(psk_cipher_state);
366 return Cipher_State::init_with_server_hello(
367 m_side, my_keyshare->take_shared_secret(), cipher, m_transcript_hash.current(), *
this);
374 auto certificate_request =
375 uses_psk ? std::nullopt
376 : Certificate_Request_13::maybe_create(client_hello, credentials_manager(), callbacks(), policy());
378 auto flight = aggregate_handshake_messages();
379 const bool is_resumption = m_handshake->resumed_session.has_value();
380 const bool requesting_client_auth = certificate_request.has_value();
382 flight.add(m_handshake->state.sending(
383 Encrypted_Extensions(client_hello, policy(), callbacks(), is_resumption, requesting_client_auth)));
390 if(certificate_request.has_value()) {
391 flight.add(m_handshake->state.sending(std::move(certificate_request.value())));
394 const auto& enc_exts = m_handshake->state.encrypted_extensions().extensions();
403 if(
auto* client_cert_type = enc_exts.get<Client_Certificate_Type>()) {
404 set_selected_certificate_type(client_cert_type->selected_certificate_type());
412 const auto cert_type = [&] {
413 if(
auto* server_cert_type = enc_exts.get<Server_Certificate_Type>()) {
414 return server_cert_type->selected_certificate_type();
416 return Certificate_Type::X509;
421 .add(m_handshake->state.sending(Certificate_13(client_hello, credentials_manager(), callbacks(), cert_type)))
422 .add(m_handshake->state.sending(Certificate_Verify_13(m_handshake->state.server_certificate(),
423 client_hello.signature_schemes(),
424 client_hello.sni_hostname(),
425 m_transcript_hash.current(),
426 Connection_Side::Server,
427 credentials_manager(),
433 flight.add(m_handshake->state.sending(Finished_13(m_cipher_state.get(), m_transcript_hash.current())));
435 if(client_hello.extensions().has<Record_Size_Limit>() &&
436 m_handshake->state.encrypted_extensions().extensions().has<Record_Size_Limit>()) {
452 auto*
const outgoing_limit = client_hello.extensions().get<Record_Size_Limit>();
453 auto*
const incoming_limit = m_handshake->state.encrypted_extensions().extensions().get<Record_Size_Limit>();
454 set_record_size_limits(outgoing_limit->limit(), incoming_limit->limit());
459 m_cipher_state->advance_with_server_finished(m_transcript_hash.current(), *
this);
461 if(m_handshake->state.has_certificate_request()) {
468 m_handshake->transitions.set_expected_next(Handshake_Type::Certificate);
470 m_handshake->transitions.set_expected_next(Handshake_Type::Finished);
474void Server_Impl_13::handle_reply_to_client_hello(Hello_Retry_Request hello_retry_request) {
475 auto cipher = Ciphersuite::by_id(hello_retry_request.ciphersuite());
478 send_handshake_message(m_handshake->state.sending(std::move(hello_retry_request)));
479 maybe_handle_compatibility_mode(Compat_Mode_Situation::AfterSendingHelloRetryRequest);
481 m_transcript_hash = Transcript_Hash_State::recreate_after_hello_retry_request(cipher->prf_algo(), m_transcript_hash);
483 m_handshake->transitions.set_expected_next(Handshake_Type::ClientHello);
486void Server_Impl_13::handle(
const Client_Hello_12_Shim& ch) {
493 if(m_handshake->state.has_hello_retry_request()) {
494 throw TLS_Exception(Alert::UnexpectedMessage,
"Received a TLS 1.2 Client Hello after Hello Retry Request");
497#if !defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
498 throw TLS_Exception(Alert::ProtocolVersion,
"Received an unsupported Client Hello");
507 if(!expects_downgrade()) {
508 throw TLS_Exception(Alert::ProtocolVersion,
"Received a legacy Client Hello");
515void Server_Impl_13::handle(
const Client_Hello_13& client_hello) {
518 const auto& exts = client_hello.extensions();
520 const bool is_initial_client_hello = !m_handshake->state.has_hello_retry_request();
522 if(is_initial_client_hello) {
523 const auto preferred_version = client_hello.highest_supported_version(policy());
524 if(!preferred_version) {
525 throw TLS_Exception(Alert::ProtocolVersion,
"No shared TLS version");
531 if(exts.has<Cookie>()) {
532 throw TLS_Exception(Alert::IllegalParameter,
"Received a Cookie in the initial client hello");
538 if(!exts.has<Supported_Groups>()) {
549 if(!is_initial_client_hello) {
550 const auto& hrr_exts = m_handshake->state.hello_retry_request().extensions();
551 const auto offered_groups = exts.get<Key_Share>()->offered_groups();
552 const auto* hrr_key_share = hrr_exts.get<Key_Share>();
554 const auto selected_group = hrr_key_share->selected_group();
555 if(offered_groups.size() != 1 || offered_groups.at(0) != selected_group) {
556 throw TLS_Exception(Alert::IllegalParameter,
"Client did not comply with the requested key exchange group");
560 callbacks().tls_examine_extensions(exts, Connection_Side::Client, client_hello.type());
561 std::visit([
this](
auto msg) { handle_reply_to_client_hello(std::move(msg)); },
562 Server_Hello_13::create(client_hello,
563 is_initial_client_hello,
565 credentials_manager(),
571void Server_Impl_13::handle(
const Certificate_13& certificate_msg) {
577 if(!is_handshake_complete() && !certificate_msg.request_context().empty()) {
578 throw TLS_Exception(Alert::DecodeError,
"Received a client certificate message with non-empty request context");
584 certificate_msg.validate_extensions(m_handshake->state.certificate_request().extensions().extension_types(),
592 if(certificate_msg.empty()) {
593 if(policy().require_client_certificate_authentication()) {
594 throw TLS_Exception(Alert::CertificateRequired,
"Policy requires client send a certificate, but it did not");
600 m_handshake->transitions.set_expected_next(Handshake_Type::Finished);
612 const bool use_ocsp = m_handshake->state.certificate_request().extensions().has<Certificate_Status_Request>();
613 certificate_msg.verify(
614 callbacks(), policy(), credentials_manager(), m_handshake->state.client_hello().sni_hostname(), use_ocsp);
621 m_handshake->transitions.set_expected_next(Handshake_Type::CertificateVerify);
625void Server_Impl_13::handle(
const Certificate_Verify_13& certificate_verify_msg) {
633 const auto offered = m_handshake->state.certificate_request().signature_schemes();
634 if(!
value_exists(offered, certificate_verify_msg.signature_scheme())) {
635 throw TLS_Exception(Alert::IllegalParameter,
636 "We did not offer the usage of " + certificate_verify_msg.signature_scheme().to_string() +
637 " as a signature scheme");
641 !m_handshake->state.client_certificate().empty());
642 const bool sig_valid = certificate_verify_msg.verify(
643 *m_handshake->state.client_certificate().public_key(), callbacks(), m_transcript_hash.previous());
649 throw TLS_Exception(Alert::DecryptError,
"Client certificate verification failed");
652 m_handshake->transitions.set_expected_next(Handshake_Type::Finished);
655void Server_Impl_13::handle(
const Finished_13& finished_msg) {
662 if(!finished_msg.verify(m_cipher_state.get(), m_transcript_hash.previous())) {
663 throw TLS_Exception(Alert::DecryptError,
"Finished message didn't verify");
666 m_handshake->state.confirm_peer_finished_verified();
670 callbacks().tls_session_established(
671 Session_Summary(m_handshake->state.server_hello(),
672 Connection_Side::Server,
674 peer_raw_public_key(),
675 m_handshake->psk_identity,
676 m_handshake->resumed_session.has_value(),
677 Server_Information(m_handshake->state.client_hello().sni_hostname()),
678 callbacks().tls_current_timestamp()));
680 m_cipher_state->advance_with_client_finished(m_transcript_hash.current());
683 m_handshake->transitions.set_expected_next({});
687 auto extract_certs = [&]() -> std::vector<X509_Certificate> {
688 if(m_handshake->state.has_client_certificate_msg() &&
689 m_handshake->state.client_certificate().has_certificate_chain()) {
690 return m_handshake->state.client_certificate().cert_chain();
692 if(m_handshake->resumed_session.has_value()) {
693 return m_handshake->resumed_session->peer_certs();
698 auto extract_raw_pk = [&]() -> std::shared_ptr<const Public_Key> {
699 if(m_handshake->state.has_client_certificate_msg() &&
700 m_handshake->state.client_certificate().is_raw_public_key()) {
701 return m_handshake->state.client_certificate().public_key();
703 if(m_handshake->resumed_session.has_value()) {
704 return m_handshake->resumed_session->peer_raw_public_key();
709 const bool supports_psk_dhe =
710 m_handshake->state.client_hello().extensions().has<PSK_Key_Exchange_Modes>() &&
711 value_exists(m_handshake->state.client_hello().extensions().get<PSK_Key_Exchange_Modes>()->modes(),
712 PSK_Key_Exchange_Mode::PSK_DHE_KE);
714 m_active_state = Active_Connection_State_13(m_handshake->state,
717 m_handshake->psk_identity,
718 m_handshake->state.client_hello().sni_hostname(),
723 m_transcript_hash = Transcript_Hash_State();
724 callbacks().tls_session_activated();
726 if(new_session_ticket_supported()) {
727 send_new_session_tickets(policy().new_session_tickets_upon_handshake_success());
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
#define BOTAN_ASSERT_UNREACHABLE()
const Policy & policy() const
AggregatedPostHandshakeMessages aggregate_post_handshake_messages()
Credentials_Manager & credentials_manager()
RandomNumberGenerator & rng()
std::optional< Active_Connection_State_13 > m_active_state
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
Callbacks & callbacks() 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
constexpr std::optional< SpecificVariantT > specialize_to(GeneralVariantT &&v)
Converts a given variant into another variant whose type states are a subset of the given variant.
bool value_exists(const std::vector< T > &vec, const V &val)
constexpr auto load_be(ParamTs &&... params)