9#include <botan/internal/tls_server_impl_13.h>
11#include <botan/credentials_manager.h>
13#include <botan/internal/loadstor.h>
14#include <botan/internal/stl_util.h>
15#include <botan/internal/tls_cipher_state.h>
20 const std::shared_ptr<Session_Manager>& session_manager,
21 const std::shared_ptr<Credentials_Manager>& credentials_manager,
22 const std::shared_ptr<const Policy>& policy,
23 const std::shared_ptr<RandomNumberGenerator>& rng) :
24 Channel_Impl_13(callbacks, session_manager, credentials_manager, rng, policy, true ) {
25#if defined(BOTAN_HAS_TLS_12)
38 return alpn->single_protocol();
51 if(m_resumed_session.has_value()) {
52 return m_resumed_session->peer_certs();
63 if(m_resumed_session.has_value()) {
64 return m_resumed_session->peer_raw_public_key();
71 return m_psk_identity;
98 size_t tickets_created = 0;
100 for(
size_t i = 0; i < tickets; ++i) {
104 policy().session_ticket_lifetime(),
112 if(
callbacks().tls_should_persist_resumption_information(session)) {
120 if(flight.contains_messages()) {
124 return tickets_created;
139 m_handshake_state.
received(std::move(message)));
145 std::visit([&](
auto msg) { handle(msg); }, m_handshake_state.
received(std::move(message)));
148void Server_Impl_13::process_dummy_change_cipher_spec() {
154 throw TLS_Exception(Alert::UnexpectedMessage,
"Received an unexpected dummy Change Cipher Spec");
170void Server_Impl_13::maybe_log_secret(std::string_view label, std::span<const uint8_t> secret)
const {
171 if(
policy().allow_ssl_key_log_file()) {
176void Server_Impl_13::downgrade() {
186void Server_Impl_13::maybe_handle_compatibility_mode() {
210 const bool just_after_first_handshake_message =
214 if(just_after_first_handshake_message &&
215 (
policy().tls_13_middlebox_compatibility_mode() || client_requested_compatibility_mode)) {
220void Server_Impl_13::handle_reply_to_client_hello(Server_Hello_13 server_hello) {
221 const auto& client_hello = m_handshake_state.
client_hello();
224 const bool uses_psk = server_hello.extensions().
has<
PSK>();
228 const auto& cipher = cipher_opt.value();
231 std::unique_ptr<Cipher_State> psk_cipher_state;
233 auto psk_extension = server_hello.extensions().get<
PSK>();
236 std::visit(
overloaded{[&,
this](Session session) {
237 m_resumed_session = std::move(session);
240 m_resumed_session->extract_master_secret(),
243 [&,
this](ExternalPSK psk) {
244 m_psk_identity = psk.identity();
247 psk.extract_master_secret(),
250 psk_extension->take_session_to_resume_or_psk());
263 if(!exts.get<
PSK>()->validate_binder(*psk_extension,
265 throw TLS_Exception(Alert::DecryptError,
"PSK binder does not check out");
286 maybe_handle_compatibility_mode();
297 psk_cipher_state->advance_with_server_hello(
300 return std::move(psk_cipher_state);
315 if(
auto certificate_request =
317 flight.add(m_handshake_state.
sending(std::move(certificate_request.value())));
329 if(
auto client_cert_type = enc_exts.get<Client_Certificate_Type>()) {
338 const auto cert_type = [&] {
339 if(
auto server_cert_type = enc_exts.get<Server_Certificate_Type>()) {
340 return server_cert_type->selected_certificate_type();
348 client_hello.signature_schemes(),
349 client_hello.sni_hostname(),
360 if(client_hello.extensions().has<Record_Size_Limit>() &&
377 const auto outgoing_limit = client_hello.extensions().get<Record_Size_Limit>();
399void Server_Impl_13::handle_reply_to_client_hello(Hello_Retry_Request hello_retry_request) {
404 maybe_handle_compatibility_mode();
411void Server_Impl_13::handle(
const Client_Hello_12& ch) {
418 throw TLS_Exception(Alert::UnexpectedMessage,
"Received a TLS 1.2 Client Hello after Hello Retry Request");
428 throw TLS_Exception(Alert::ProtocolVersion,
"Received a legacy Client Hello");
434void Server_Impl_13::handle(
const Client_Hello_13& client_hello) {
435 const auto& exts = client_hello.extensions();
439 if(is_initial_client_hello) {
440 const auto preferred_version = client_hello.highest_supported_version(
policy());
441 if(!preferred_version) {
442 throw TLS_Exception(Alert::ProtocolVersion,
"No shared TLS version");
449 throw TLS_Exception(Alert::IllegalParameter,
"Received a Cookie in the initial client hello");
455 if(!exts.has<Supported_Groups>()) {
456 throw Not_Implemented(
"PSK-only handshake NYI");
466 if(!is_initial_client_hello) {
468 const auto offered_groups = exts.
get<Key_Share>()->offered_groups();
469 const auto selected_group = hrr_exts.get<Key_Share>()->selected_group();
470 if(offered_groups.size() != 1 || offered_groups.at(0) != selected_group) {
471 throw TLS_Exception(Alert::IllegalParameter,
"Client did not comply with the requested key exchange group");
476 std::visit([
this](
auto msg) { handle_reply_to_client_hello(std::move(msg)); },
478 is_initial_client_hello,
486void Server_Impl_13::handle(
const Certificate_13& certificate_msg) {
491 throw TLS_Exception(Alert::DecodeError,
"Received a client certificate message with non-empty request context");
505 if(certificate_msg.empty()) {
506 if(
policy().require_client_certificate_authentication()) {
507 throw TLS_Exception(Alert::CertificateRequired,
"Policy requires client send a certificate, but it did not");
539void Server_Impl_13::handle(
const Certificate_Verify_13& certificate_verify_msg) {
546 if(!
value_exists(offered, certificate_verify_msg.signature_scheme())) {
547 throw TLS_Exception(Alert::IllegalParameter,
548 "We did not offer the usage of " + certificate_verify_msg.signature_scheme().to_string() +
549 " as a signature scheme");
554 bool sig_valid = certificate_verify_msg.verify(
561 throw TLS_Exception(Alert::DecryptError,
"Client certificate verification failed");
567void Server_Impl_13::handle(
const Finished_13& finished_msg) {
573 throw TLS_Exception(Alert::DecryptError,
"Finished message didn't verify");
584 m_resumed_session.has_value(),
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
virtual void tls_session_established(const Session_Summary &session)
virtual void tls_session_activated()
virtual void tls_ssl_key_log_data(std::string_view label, std::span< const uint8_t > client_random, std::span< const uint8_t > secret) const
virtual void tls_examine_extensions(const Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
virtual void tls_inspect_handshake_msg(const Handshake_Message &message)
std::shared_ptr< const Public_Key > public_key() const
bool is_raw_public_key() const
std::vector< X509_Certificate > cert_chain() const
bool has_certificate_chain() const
const std::vector< Signature_Scheme > & signature_schemes() const
const Extensions & extensions() const
static std::optional< Certificate_Request_13 > maybe_create(const Client_Hello_13 &sni_hostname, Credentials_Manager &cred_mgr, Callbacks &callbacks, const Policy &policy)
const Policy & policy() const
AggregatedPostHandshakeMessages aggregate_post_handshake_messages()
void expect_downgrade(const Server_Information &server_info, const std::vector< std::string > &next_protocols)
AggregatedHandshakeMessages aggregate_handshake_messages()
Credentials_Manager & credentials_manager()
void send_dummy_change_cipher_spec()
RandomNumberGenerator & rng()
std::vector< uint8_t > send_handshake_message(const std::variant< MsgTs... > &message)
Transcript_Hash_State m_transcript_hash
Session_Manager & session_manager()
std::unique_ptr< Cipher_State > m_cipher_state
const Connection_Side m_side
Callbacks & callbacks() const
void set_selected_certificate_type(Certificate_Type cert_type)
void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit)
bool expects_downgrade() const
static std::unique_ptr< 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 std::unique_ptr< Cipher_State > init_with_psk(Connection_Side side, PSK_Type type, secure_vector< uint8_t > &&psk, std::string_view prf_algo)
static std::optional< Ciphersuite > by_id(uint16_t suite)
std::string sni_hostname() const
const std::vector< uint8_t > & random() const
const Extensions & extensions() const
const Session_ID & session_id() const
const Extensions & extensions() const
std::set< Extension_Code > extension_types() const
std::reference_wrapper< MsgT > sending(MsgT msg)
decltype(auto) received(Handshake_Message_13 message)
void confirm_transition_to(Handshake_Type msg_type)
void set_expected_next(Handshake_Type msg_type)
bool has_certificate_request() const
bool has_server_hello() const
bool has_hello_retry_request() const
Client_Hello_13 & client_hello()
const Hello_Retry_Request & hello_retry_request() const
bool has_client_finished() const
const Certificate_13 & server_certificate() const
bool has_client_certificate_msg() const
const Certificate_Request_13 & certificate_request() const
const Certificate_13 & client_certificate() const
bool has_client_hello() const
const Encrypted_Extensions & encrypted_extensions() const
const Server_Hello_13 & server_hello() const
bool handshake_finished() const
virtual bool allow_tls12() const
static std::variant< Hello_Retry_Request, Server_Hello_13 > create(const Client_Hello_13 &ch, bool hello_retry_request_allowed, Session_Manager &session_mgr, Credentials_Manager &credentials_mgr, RandomNumberGenerator &rng, const Policy &policy, Callbacks &cb)
const Extensions & extensions() 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)
const Transcript_Hash & current() const
static Transcript_Hash_State recreate_after_hello_retry_request(std::string_view algo_spec, const Transcript_Hash_State &prev_transcript_hash_state)
void set_algorithm(std::string_view algo_spec)
const Transcript_Hash & previous() const
const Transcript_Hash & truncated() const
std::variant< New_Session_Ticket_13, Key_Update > Post_Handshake_Message_13
std::variant< Client_Hello_13, Client_Hello_12, Server_Hello_13, Server_Hello_12, 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 OT &val)
overloaded(Ts...) -> overloaded< Ts... >