12#include <botan/tls_messages.h>
14#include <botan/hash.h>
16#include <botan/tls_callbacks.h>
17#include <botan/tls_exceptn.h>
18#include <botan/tls_version.h>
20#include <botan/internal/parsing.h>
21#include <botan/internal/stl_util.h>
22#include <botan/internal/tls_handshake_hash.h>
23#include <botan/internal/tls_handshake_io.h>
24#include <botan/internal/tls_reader.h>
26#ifdef BOTAN_HAS_TLS_13
27 #include <botan/internal/tls_handshake_layer_13.h>
28 #include <botan/internal/tls_transcript_hash_13.h>
37 auto buf = rng.
random_vec<std::vector<uint8_t>>(32);
49 const uint32_t time32 =
static_cast<uint32_t
>(std::chrono::system_clock::to_time_t(cb.
tls_current_timestamp()));
62class Client_Hello_Internal {
64 Client_Hello_Internal() : m_comp_methods({0}) {}
66 explicit Client_Hello_Internal(
const std::vector<uint8_t>& buf) {
68 throw Decoding_Error(
"Client_Hello: Packet corrupted");
71 TLS_Data_Reader reader(
"ClientHello", buf);
73 const uint8_t major_version = reader.get_byte();
74 const uint8_t minor_version = reader.get_byte();
76 m_legacy_version = Protocol_Version(major_version, minor_version);
77 m_random = reader.get_fixed<uint8_t>(32);
78 m_session_id =
Session_ID(reader.get_range<uint8_t>(1, 0, 32));
80 if(m_legacy_version.is_datagram_protocol()) {
82 sha256->update(reader.get_data_read_so_far());
84 m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
86 sha256->update(reader.get_remaining());
87 m_cookie_input_bits = sha256->final_stdvec();
90 m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
91 m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
122 !
extensions().get<Supported_Versions>()->supports(Protocol_Version::TLS_V13)) {
125 return (m_legacy_version.
is_datagram_protocol()) ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
130 return Protocol_Version::TLS_V13;
135 const Session_ID& session_id()
const {
return m_session_id; }
137 const std::vector<uint8_t>& random()
const {
return m_random; }
139 const std::vector<uint16_t>& ciphersuites()
const {
return m_suites; }
141 const std::vector<uint8_t>& comp_methods()
const {
return m_comp_methods; }
143 const std::vector<uint8_t>& hello_cookie()
const {
return m_hello_cookie; }
145 const std::vector<uint8_t>& hello_cookie_input_bits()
const {
return m_cookie_input_bits; }
147 const Extensions& extensions()
const {
return m_extensions; }
149 Extensions& extensions() {
return m_extensions; }
152 Protocol_Version m_legacy_version;
154 std::vector<uint8_t> m_random;
155 std::vector<uint16_t> m_suites;
156 std::vector<uint8_t> m_comp_methods;
157 Extensions m_extensions;
160 std::vector<uint8_t> m_hello_cookie;
161 std::vector<uint8_t> m_cookie_input_bits;
183 return m_data->legacy_version();
191 return m_data->session_id();
195 return m_data->comp_methods();
199 return m_data->ciphersuites();
203 return m_data->extensions().extension_types();
207 return m_data->extensions();
220 std::vector<uint8_t> buf;
223 buf.push_back(
m_data->legacy_version().major_version());
224 buf.push_back(
m_data->legacy_version().minor_version());
229 if(
m_data->legacy_version().is_datagram_protocol()) {
250 return m_data->hello_cookie_input_bits();
257 return std::find(
m_data->ciphersuites().cbegin(),
m_data->ciphersuites().cend(), ciphersuite) !=
258 m_data->ciphersuites().cend();
263 return sigs->supported_schemes();
274 return sigs->supported_schemes();
282 return groups->ec_groups();
289 return groups->dh_groups();
291 return std::vector<Group_Params>();
296 return ecc_formats->prefers_compressed();
303 return sni->host_name();
314 return reneg->renegotiation_info();
321 return versions->versions();
332 return ticket->contents();
373 return alpn->protocols();
380 return srtp->profiles();
386 return m_data->hello_cookie();
409 return std::vector<uint8_t>();
412void Client_Hello_12::add_tls12_supported_groups_extensions(
const Policy& policy) {
418 const std::vector<Group_Params> kex_groups = policy.key_exchange_groups();
419 std::vector<Group_Params> compatible_kex_groups;
420 std::copy_if(kex_groups.begin(), kex_groups.end(), std::back_inserter(compatible_kex_groups), [](
const auto group) {
421 return !group.is_post_quantum();
424 auto supported_groups = std::make_unique<Supported_Groups>(std::move(compatible_kex_groups));
426 if(!supported_groups->ec_groups().empty()) {
428 m_data->extensions().add(
new Supported_Point_Formats(policy.use_ecc_point_compression()));
431 m_data->extensions().add(std::move(supported_groups));
435 const uint16_t TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF;
437 if(
offered_suite(
static_cast<uint16_t
>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV))) {
439 if(!reneg->renegotiation_info().empty()) {
440 throw TLS_Exception(Alert::HandshakeFailure,
"Client sent renegotiation SCSV and non-empty extension");
452bool hostname_acceptable_for_sni(std::string_view hostname) {
453 if(hostname.empty()) {
462 if(hostname.find(
':') != std::string_view::npos) {
484 const std::vector<uint8_t>& reneg_info,
493 " but our own policy does not accept it");
517 if(hostname_acceptable_for_sni(client_settings.
hostname())) {
525 add_tls12_supported_groups_extensions(policy);
540 if(
m_data->legacy_version().is_datagram_protocol()) {
559 const std::vector<uint8_t>& reneg_info,
575 " but our own policy does not accept it");
603 if(hostname_acceptable_for_sni(hostname)) {
611 add_tls12_supported_groups_extensions(policy);
632#if defined(BOTAN_HAS_TLS_13)
649 if(
m_data->legacy_version().is_tls_13_or_later()) {
650 throw TLS_Exception(Alert::DecodeError,
"TLS 1.3 Client Hello has invalid legacy_version");
658 if(
m_data->comp_methods().size() != 1 ||
m_data->comp_methods().front() != 0) {
659 throw TLS_Exception(Alert::IllegalParameter,
"Client did not offer NULL compression");
667 if(exts.has<
PSK>()) {
668 if(!exts.has<PSK_Key_Exchange_Modes>()) {
669 throw TLS_Exception(Alert::MissingExtension,
670 "Client Hello offered a PSK without a psk_key_exchange_modes extension");
678 throw TLS_Exception(Alert::IllegalParameter,
"PSK extension was not at the very end of the Client Hello");
696 if(!exts.has<
PSK>()) {
697 if(!exts.has<Supported_Groups>() || !exts.has<Signature_Algorithms>()) {
699 Alert::MissingExtension,
700 "Non-PSK Client Hello did not contain supported_groups and signature_algorithms extensions");
703 if(exts.has<Supported_Groups>() != exts.has<Key_Share>()) {
704 throw TLS_Exception(Alert::MissingExtension,
705 "Client Hello must either contain both key_share and supported_groups extensions or neither");
708 if(exts.has<Key_Share>()) {
709 auto*
const supported_ext = exts.get<Supported_Groups>();
711 const auto supports = supported_ext->groups();
712 const auto offers = exts.get<Key_Share>()->offered_groups();
723 auto found_in_supported_groups = [&supports, support_offset = -1](
auto group)
mutable {
724 const auto i = std::find(supports.begin(), supports.end(), group);
725 if(i == supports.end()) {
729 const auto found_at = std::distance(supports.begin(), i);
730 if(found_at <= support_offset) {
735 support_offset =
static_cast<decltype(support_offset)
>(found_at);
739 for(
const auto offered : offers) {
743 if(!found_in_supported_groups(offered)) {
744 throw TLS_Exception(Alert::IllegalParameter,
745 "Offered key exchange groups do not align with claimed supported groups");
762 std::string_view hostname,
764 std::optional<Session_with_Handle>& session,
765 std::vector<ExternalPSK> psks) {
771 m_data->m_legacy_version = Protocol_Version::TLS_V12;
777 const auto legacy_suites = policy.
ciphersuite_list(Protocol_Version::TLS_V12);
778 m_data->m_suites.insert(
m_data->m_suites.end(), legacy_suites.cbegin(), legacy_suites.cend());
793 if(hostname_acceptable_for_sni(hostname)) {
855 if(session.has_value() || !psks.empty()) {
856 m_data->extensions().add(
new PSK(session, std::move(psks), cb));
868 "Application modified extensions of Client Hello, PSK is not last anymore");
870 calculate_psk_binders({});
875 auto data = std::make_unique<Client_Hello_Internal>(buf);
876 const auto version = data->version();
878 if(version.is_pre_tls_13()) {
896 m_data->extensions().get<
Key_Share>()->retry_offer(*hrr_ks, supported_groups, cb, rng);
918 auto* psk =
m_data->extensions().get<
PSK>();
928 psk->filter(cipher.value());
933 calculate_psk_binders(transcript_hash_state.
clone());
944 m_data->ciphersuites() != new_ch.
m_data->ciphersuites() ||
945 m_data->comp_methods() != new_ch.
m_data->comp_methods()) {
946 throw TLS_Exception(Alert::IllegalParameter,
"Client Hello core values changed after Hello Retry Request");
953 for(
const auto oldext : oldexts) {
954 if(!newexts.contains(oldext)) {
958 if(!ext->is_implemented()) {
977 throw TLS_Exception(Alert::IllegalParameter,
"Extension removed in updated Client Hello");
982 for(
const auto newext : newexts) {
983 if(!oldexts.contains(newext)) {
987 if(!ext->is_implemented()) {
1006 throw TLS_Exception(Alert::UnsupportedExtension,
"Added an extension in updated Client Hello");
1014 throw TLS_Exception(Alert::IllegalParameter,
"Updated Client Hello indicates early data");
1034 auto* psk =
m_data->extensions().get<
PSK>();
1035 if(psk ==
nullptr || psk->empty()) {
1049 psk->calculate_binders(transcript_hash);
1061 std::optional<Protocol_Version> result;
1063 for(
const auto& v : supvers->versions()) {
1072 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)
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
void random_vec(std::span< uint8_t > v)
virtual void tls_modify_extensions(Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
virtual std::chrono::system_clock::time_point tls_current_timestamp()
static std::optional< Ciphersuite > by_id(uint16_t suite)
const std::string & hostname() const
Protocol_Version protocol_version() const
Client_Hello_12(const std::vector< uint8_t > &buf)
void update_hello_cookie(const Hello_Verify_Request &hello_verify)
std::vector< uint8_t > renegotiation_info() const
bool supports_encrypt_then_mac() const
Session_Ticket session_ticket() const
bool supports_cert_status_message() const
bool secure_renegotiation() const
bool supports_extended_master_secret() const
std::optional< Session_Handle > session_handle() const
bool supports_session_ticket() const
bool prefers_compressed_ec_points() const
void validate_updates(const Client_Hello_13 &new_ch)
static std::variant< Client_Hello_13, Client_Hello_12 > 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 std::vector< uint8_t > & cookie() const
std::string sni_hostname() const
std::vector< uint8_t > serialize() const override
const std::vector< uint8_t > & random() const
std::vector< Signature_Scheme > signature_schemes() const
const Extensions & extensions() const
bool offered_suite(uint16_t ciphersuite) const
std::unique_ptr< Client_Hello_Internal > m_data
bool sent_signature_algorithms() const
std::vector< Group_Params > supported_ecc_curves() const
bool supports_alpn() const
std::vector< Signature_Scheme > certificate_signature_schemes() const
const std::vector< uint16_t > & ciphersuites() const
std::vector< uint8_t > cookie_input_data() const
std::set< Extension_Code > extension_types() const
std::vector< Group_Params > supported_dh_groups() const
std::vector< std::string > next_protocols() const
const Session_ID & session_id() const
Protocol_Version legacy_version() const
const std::vector< uint8_t > & compression_methods() const
std::vector< uint16_t > srtp_profiles() const
Handshake_Type type() const override
std::vector< Protocol_Version > supported_versions() const
Client_Hello(const Client_Hello &)=delete
const std::vector< uint8_t > & get_cookie() const
static Extension_Code static_type()
static Extension_Code static_type()
void update(const uint8_t in[], size_t length)
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
static std::vector< uint8_t > prepare_message(Handshake_Message_13_Ref message, Transcript_Hash_State &transcript_hash)
virtual std::vector< uint8_t > serialize() const =0
Hello_Request(Handshake_IO &io)
const std::vector< uint8_t > & cookie() const
virtual bool include_time_in_hello_random() 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 std::vector< uint16_t > srtp_profiles() const
virtual bool support_cert_status_message() const
virtual std::optional< std::vector< Signature_Scheme > > acceptable_certificate_signature_schemes() const
virtual bool hash_hello_random() const
virtual std::vector< Signature_Scheme > acceptable_signature_schemes() const
virtual bool use_ecc_point_compression() const
virtual bool allow_dtls12() const
virtual std::optional< uint16_t > record_size_limit() const
bool is_datagram_protocol() const
uint16_t ciphersuite() const
const Extensions & extensions() const
Protocol_Version version() const
bool supports_encrypt_then_mac() const
uint16_t ciphersuite_code() const
const Server_Information & server_info() const
Helper class to embody a session handle in all protocol versions.
std::optional< Session_Ticket > ticket() const
std::optional< Session_ID > id() const
std::vector< Group_Params > ec_groups() const
Transcript_Hash_State clone() const
bool empty() const noexcept(noexcept(this->get().empty()))
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
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
Strong< std::vector< uint8_t >, struct Session_Ticket_ > Session_Ticket
holds a TLS 1.2 session ticket for stateless resumption
bool value_exists(const std::vector< T > &vec, const V &val)
std::optional< uint32_t > string_to_ipv4(std::string_view str)
constexpr auto store_be(ParamTs &&... params)