11#include <botan/tls_messages_13.h>
13#include <botan/assert.h>
14#include <botan/tls_alert.h>
15#include <botan/tls_callbacks.h>
16#include <botan/tls_exceptn.h>
17#include <botan/tls_extensions_13.h>
18#include <botan/tls_policy.h>
19#include <botan/internal/tls_handshake_layer_13.h>
20#include <botan/internal/tls_messages_internal.h>
21#include <botan/internal/tls_transcript_hash_13.h>
24#if defined(BOTAN_HAS_TLS_12)
25 #include <botan/tls_extensions_12.h>
45 if(m_data->legacy_version().is_tls_13_or_later()) {
46 throw TLS_Exception(Alert::DecodeError,
"TLS 1.3 Client Hello has invalid legacy_version");
52 if(m_data->legacy_version().major_version() == 3 && m_data->legacy_version().minor_version() == 0) {
53 throw TLS_Exception(Alert::ProtocolVersion,
"TLS 1.3 Client Hello has invalid legacy_version");
61 if(m_data->comp_methods().size() != 1 || m_data->comp_methods().front() != 0) {
62 throw TLS_Exception(Alert::IllegalParameter,
"Client did not offer NULL compression");
71 if(!exts.has<PSK_Key_Exchange_Modes>()) {
72 throw TLS_Exception(Alert::MissingExtension,
73 "Client Hello offered a PSK without a psk_key_exchange_modes extension");
80 if(exts.last_added() != Extension_Code::PresharedKey) {
81 throw TLS_Exception(Alert::IllegalParameter,
"PSK extension was not at the very end of the Client Hello");
99 if(!exts.has<PSK>()) {
100 if(!exts.has<Supported_Groups>() || !exts.has<Signature_Algorithms>()) {
102 Alert::MissingExtension,
103 "Non-PSK Client Hello did not contain supported_groups and signature_algorithms extensions");
106 if(exts.has<Supported_Groups>() != exts.has<Key_Share>()) {
107 throw TLS_Exception(Alert::MissingExtension,
108 "Client Hello must either contain both key_share and supported_groups extensions or neither");
111 if(exts.has<Key_Share>()) {
112 auto*
const supported_ext = exts.get<Supported_Groups>();
114 const auto supports = supported_ext->groups();
115 const auto offers = exts.get<Key_Share>()->offered_groups();
134 auto supports_it = supports.begin();
135 for(
const auto offered : offers) {
136 supports_it = std::find(supports_it, supports.end(), offered);
137 if(supports_it == supports.end()) {
138 throw TLS_Exception(Alert::IllegalParameter,
139 "Offered key exchange groups do not align with claimed supported groups");
157 std::string_view hostname,
159 std::optional<Session_with_Handle>& session,
160 std::vector<ExternalPSK> psks) {
166 m_data->m_legacy_version = Protocol_Version::TLS_V12;
172 const auto legacy_suites = policy.
ciphersuite_list(Protocol_Version::TLS_V12);
173 m_data->m_suites.insert(
m_data->m_suites.end(), legacy_suites.cbegin(), legacy_suites.cend());
237#if defined(BOTAN_HAS_TLS_12)
256 if(session.has_value() || !psks.empty()) {
257 m_data->extensions().add(
new PSK(session, std::move(psks), cb));
267 "Application tls_modify_extensions callback removed Supported_Groups from the ClientHello");
271 "Application tls_modify_extensions callback removed Key_Share from the ClientHello");
280 "Application modified extensions of Client Hello, PSK is not last anymore");
282 calculate_psk_binders({});
287 auto data = std::make_unique<Client_Hello_Internal>(buf);
288 const auto version = data->version();
290 if(version.is_pre_tls_13()) {
308 m_data->extensions().get<
Key_Share>()->retry_offer(*hrr_ks, supported_groups, cb, rng);
334 Alert::InternalError,
335 "Application tls_modify_extensions callback removed Supported_Groups from the retried ClientHello");
339 "Application tls_modify_extensions callback removed Key_Share from the retried ClientHello");
342 auto* psk =
m_data->extensions().get<
PSK>();
357 psk->filter(cipher.value());
362 calculate_psk_binders(transcript_hash_state.
clone());
373 m_data->ciphersuites() != new_ch.
m_data->ciphersuites() ||
374 m_data->comp_methods() != new_ch.
m_data->comp_methods()) {
375 throw TLS_Exception(Alert::IllegalParameter,
"Client Hello core values changed after Hello Retry Request");
385 for(
const auto oldext : oldexts) {
386 if(!newexts.contains(oldext)) {
401 throw TLS_Exception(Alert::IllegalParameter,
"Extension removed in updated Client Hello");
407 for(
const auto newext : newexts) {
408 if(!oldexts.contains(newext)) {
423 throw TLS_Exception(Alert::UnsupportedExtension,
"Added an extension in updated Client Hello");
431 throw TLS_Exception(Alert::IllegalParameter,
"Updated Client Hello indicates early data");
440 const std::set<Extension_Code> extensions_allowed_to_change = {
448 for(
const auto ext_type : oldexts) {
449 if(extensions_allowed_to_change.contains(ext_type)) {
453 const auto old_bytes =
extensions().extension_raw_bytes(ext_type);
461 if(old_bytes.value() != new_bytes.value()) {
462 throw TLS_Exception(Alert::IllegalParameter,
"Extension content changed in updated Client Hello");
468 auto* psk = m_data->extensions().get<
PSK>();
469 if(psk ==
nullptr || psk->empty()) {
482 Handshake_Layer::prepare_message(*
this, transcript_hash);
483 psk->calculate_binders(transcript_hash);
495 std::optional<Protocol_Version> result;
497 for(
const auto& v : supvers->versions()) {
506 result = (result.has_value()) ? std::optional(std::max(result.value(), v)) : std::optional(v);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
virtual void tls_modify_extensions(Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
static std::optional< Ciphersuite > by_id(uint16_t suite)
void validate_updates(const Client_Hello_13 &new_ch)
static std::variant< Client_Hello_13, Client_Hello_12_Shim > parse(const std::vector< uint8_t > &buf)
std::optional< Protocol_Version > highest_supported_version(const Policy &policy) const
Client_Hello_13(const Policy &policy, Callbacks &cb, RandomNumberGenerator &rng, std::string_view hostname, const std::vector< std::string > &next_protocols, std::optional< Session_with_Handle > &session, std::vector< ExternalPSK > psks)
void retry(const Hello_Retry_Request &hrr, const Transcript_Hash_State &transcript_hash_state, Callbacks &cb, RandomNumberGenerator &rng)
const Extensions & extensions() const
std::unique_ptr< Client_Hello_Internal > m_data
std::set< Extension_Code > extension_types() const
std::vector< std::string > next_protocols() const
Handshake_Type type() const override
const std::vector< uint8_t > & get_cookie() const
static Extension_Code static_type()
static Extension_Code static_type()
std::optional< std::vector< uint8_t > > extension_raw_bytes(Extension_Code type) const
virtual bool allow_tls12() const
virtual std::vector< uint16_t > ciphersuite_list(Protocol_Version version) const
virtual std::vector< Certificate_Type > accepted_server_certificate_types() const
virtual std::vector< Certificate_Type > accepted_client_certificate_types() const
virtual std::vector< Group_Params > key_exchange_groups() const
virtual bool tls_13_middlebox_compatibility_mode() const
virtual bool negotiate_encrypt_then_mac() const
virtual bool acceptable_protocol_version(Protocol_Version version) const
virtual bool support_cert_status_message() const
virtual std::optional< std::vector< Signature_Scheme > > acceptable_certificate_signature_schemes() const
virtual std::vector< Signature_Scheme > acceptable_signature_schemes() const
virtual bool use_ecc_point_compression() const
virtual std::optional< uint16_t > record_size_limit() const
uint16_t ciphersuite() const
const Extensions & extensions() const
static bool hostname_acceptable_for_sni(std::string_view hostname)
std::vector< Group_Params > ec_groups() const
Transcript_Hash_State clone() const
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, Callbacks &cb, const Policy &policy)
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption