12#include <botan/tls_messages.h>
14#include <botan/credentials_manager.h>
15#include <botan/hash.h>
17#include <botan/tls_callbacks.h>
18#include <botan/tls_exceptn.h>
19#include <botan/tls_version.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>
25#include <botan/internal/tls_session_key.h>
27#ifdef BOTAN_HAS_TLS_13
28 #include <botan/internal/tls_handshake_layer_13.h>
29 #include <botan/internal/tls_transcript_hash_13.h>
42 auto buf = rng.
random_vec<std::vector<uint8_t>>(32);
54 const uint32_t time32 =
static_cast<uint32_t
>(std::chrono::system_clock::to_time_t(cb.
tls_current_timestamp()));
67class Client_Hello_Internal {
69 Client_Hello_Internal() : m_comp_methods({0}) {}
71 Client_Hello_Internal(
const std::vector<uint8_t>& buf) {
73 throw Decoding_Error(
"Client_Hello: Packet corrupted");
76 TLS_Data_Reader reader(
"ClientHello", buf);
78 const uint8_t major_version = reader.get_byte();
79 const uint8_t minor_version = reader.get_byte();
81 m_legacy_version = Protocol_Version(major_version, minor_version);
82 m_random = reader.get_fixed<uint8_t>(32);
83 m_session_id =
Session_ID(reader.get_range<uint8_t>(1, 0, 32));
87 sha256->update(reader.get_data_read_so_far());
89 m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
91 sha256->update(reader.get_remaining());
92 m_cookie_input_bits = sha256->final_stdvec();
95 m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
96 m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
126 if(!extensions().has<Supported_Versions>() ||
127 !extensions().get<Supported_Versions>()->supports(Protocol_Version::TLS_V13)) {
130 return (m_legacy_version.
is_datagram_protocol()) ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
135 return Protocol_Version::TLS_V13;
138 Protocol_Version legacy_version()
const {
return m_legacy_version; }
140 const Session_ID& session_id()
const {
return m_session_id; }
142 const std::vector<uint8_t>& random()
const {
return m_random; }
144 const std::vector<uint16_t>& ciphersuites()
const {
return m_suites; }
146 const std::vector<uint8_t>& comp_methods()
const {
return m_comp_methods; }
148 const std::vector<uint8_t>& hello_cookie()
const {
return m_hello_cookie; }
150 const std::vector<uint8_t>& hello_cookie_input_bits()
const {
return m_cookie_input_bits; }
152 const Extensions& extensions()
const {
return m_extensions; }
154 Extensions& extensions() {
return m_extensions; }
157 Protocol_Version m_legacy_version;
159 std::vector<uint8_t> m_random;
160 std::vector<uint16_t> m_suites;
161 std::vector<uint8_t> m_comp_methods;
162 Extensions m_extensions;
165 std::vector<uint8_t> m_hello_cookie;
166 std::vector<uint8_t> m_cookie_input_bits;
170Client_Hello& Client_Hello::operator=(Client_Hello&&) noexcept = default;
172Client_Hello::~Client_Hello() = default;
188 return m_data->legacy_version();
196 return m_data->session_id();
200 return m_data->comp_methods();
204 return m_data->ciphersuites();
208 return m_data->extensions().extension_types();
212 return m_data->extensions();
225 std::vector<uint8_t> buf;
228 buf.push_back(
m_data->legacy_version().major_version());
229 buf.push_back(
m_data->legacy_version().minor_version());
234 if(
m_data->legacy_version().is_datagram_protocol()) {
255 return m_data->hello_cookie_input_bits();
262 return std::find(
m_data->ciphersuites().cbegin(),
m_data->ciphersuites().cend(), ciphersuite) !=
263 m_data->ciphersuites().cend();
268 return sigs->supported_schemes();
279 return sigs->supported_schemes();
287 return groups->ec_groups();
294 return groups->dh_groups();
296 return std::vector<Group_Params>();
301 return ecc_formats->prefers_compressed();
308 return sni->host_name();
326 return versions->versions();
337 return ticket->contents();
349 }
else if(
const auto&
id =
session_id(); !
id.empty()) {
378 return alpn->protocols();
385 return srtp->profiles();
391 return m_data->hello_cookie();
413std::vector<uint8_t> Hello_Request::serialize()
const {
414 return std::vector<uint8_t>();
417void Client_Hello_12::add_tls12_supported_groups_extensions(
const Policy& policy) {
423 const std::vector<Group_Params> kex_groups = policy.key_exchange_groups();
424 std::vector<Group_Params> compatible_kex_groups;
425 std::copy_if(kex_groups.begin(), kex_groups.end(), std::back_inserter(compatible_kex_groups), [](
const auto group) {
426 return !group.is_post_quantum();
429 auto supported_groups = std::make_unique<Supported_Groups>(std::move(compatible_kex_groups));
431 if(!supported_groups->ec_groups().empty()) {
432 m_data->extensions().add(
new Supported_Point_Formats(policy.use_ecc_point_compression()));
435 m_data->extensions().add(std::move(supported_groups));
441 if(!reneg->renegotiation_info().empty()) {
442 throw TLS_Exception(Alert::HandshakeFailure,
"Client sent renegotiation SCSV and non-empty extension");
464 const std::vector<uint8_t>& reneg_info,
466 const std::vector<std::string>& next_protocols) {
473 " but our own policy does not accept it");
494 if(!client_settings.
hostname().empty()) {
502 add_tls12_supported_groups_extensions(policy);
517 if(
m_data->legacy_version().is_datagram_protocol()) {
534 const std::vector<uint8_t>& reneg_info,
536 const std::vector<std::string>& next_protocols) {
550 " but our own policy does not accept it");
581 add_tls12_supported_groups_extensions(policy);
601#if defined(BOTAN_HAS_TLS_13)
618 if(
m_data->legacy_version().is_tls_13_or_later()) {
619 throw TLS_Exception(Alert::DecodeError,
"TLS 1.3 Client Hello has invalid legacy_version");
627 if(
m_data->comp_methods().size() != 1 ||
m_data->comp_methods().front() != 0) {
628 throw TLS_Exception(Alert::IllegalParameter,
"Client did not offer NULL compression");
636 if(exts.has<
PSK>()) {
637 if(!exts.has<PSK_Key_Exchange_Modes>()) {
638 throw TLS_Exception(Alert::MissingExtension,
639 "Client Hello offered a PSK without a psk_key_exchange_modes extension");
647 throw TLS_Exception(Alert::IllegalParameter,
"PSK extension was not at the very end of the Client Hello");
665 if(!exts.has<
PSK>()) {
666 if(!exts.has<Supported_Groups>() || !exts.has<Signature_Algorithms>()) {
668 Alert::MissingExtension,
669 "Non-PSK Client Hello did not contain supported_groups and signature_algorithms extensions");
672 if(exts.has<Supported_Groups>() != exts.has<Key_Share>()) {
673 throw TLS_Exception(Alert::MissingExtension,
674 "Client Hello must either contain both key_share and supported_groups extensions or neither");
677 if(exts.has<Key_Share>()) {
678 const auto supported_ext = exts.get<Supported_Groups>();
680 const auto supports = supported_ext->groups();
681 const auto offers = exts.get<Key_Share>()->offered_groups();
692 auto found_in_supported_groups = [&supports, support_offset = -1](
auto group)
mutable {
693 const auto i = std::find(supports.begin(), supports.end(), group);
694 if(i == supports.end()) {
698 const auto found_at = std::distance(supports.begin(), i);
699 if(found_at <= support_offset) {
704 support_offset =
static_cast<decltype(support_offset)
>(found_at);
708 for(
const auto offered : offers) {
712 if(!found_in_supported_groups(offered)) {
713 throw TLS_Exception(Alert::IllegalParameter,
714 "Offered key exchange groups do not align with claimed supported groups");
731 std::string_view hostname,
732 const std::vector<std::string>& next_protocols,
733 std::optional<Session_with_Handle>& session,
734 std::vector<ExternalPSK> psks) {
740 m_data->m_legacy_version = Protocol_Version::TLS_V12;
746 const auto legacy_suites = policy.
ciphersuite_list(Protocol_Version::TLS_V12);
747 m_data->m_suites.insert(
m_data->m_suites.end(), legacy_suites.cbegin(), legacy_suites.cend());
761 if(!hostname.empty()) {
823 if(session.has_value() || !psks.empty()) {
824 m_data->extensions().add(
new PSK(session, std::move(psks), cb));
835 "Application modified extensions of Client Hello, PSK is not last anymore");
837 calculate_psk_binders({});
842 auto data = std::make_unique<Client_Hello_Internal>(buf);
843 const auto version = data->version();
845 if(version.is_pre_tls_13()) {
863 m_data->extensions().get<
Key_Share>()->retry_offer(*hrr_ks, supported_groups, cb, rng);
885 auto psk =
m_data->extensions().get<
PSK>();
895 psk->filter(cipher.value());
900 calculate_psk_binders(transcript_hash_state.
clone());
911 m_data->ciphersuites() != new_ch.
m_data->ciphersuites() ||
912 m_data->comp_methods() != new_ch.
m_data->comp_methods()) {
913 throw TLS_Exception(Alert::IllegalParameter,
"Client Hello core values changed after Hello Retry Request");
920 for(
const auto oldext : oldexts) {
921 if(!newexts.contains(oldext)) {
925 if(!ext->is_implemented()) {
944 throw TLS_Exception(Alert::IllegalParameter,
"Extension removed in updated Client Hello");
949 for(
const auto newext : newexts) {
950 if(!oldexts.contains(newext)) {
954 if(!ext->is_implemented()) {
973 throw TLS_Exception(Alert::UnsupportedExtension,
"Added an extension in updated Client Hello");
981 throw TLS_Exception(Alert::IllegalParameter,
"Updated Client Hello indicates early data");
1001 auto psk =
m_data->extensions().get<
PSK>();
1002 if(!psk || psk->empty()) {
1016 psk->calculate_binders(ths);
1028 std::optional<Protocol_Version> result;
1030 for(
const auto& v : supvers->versions()) {
1039 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
const std::vector< uint8_t > & get_cookie() const
static Extension_Code static_type()
static Extension_Code static_type()
void deserialize(TLS_Data_Reader &reader, Connection_Side from, Handshake_Type message_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)
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
const std::vector< uint8_t > & renegotiation_info() 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
std::optional< Session_Ticket > ticket() const
std::optional< Session_ID > id() const
std::vector< Group_Params > ec_groups() const
Transcript_Hash_State clone() const
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
@ TLS_EMPTY_RENEGOTIATION_INFO_SCSV
bool value_exists(const std::vector< T > &vec, const OT &val)
constexpr auto store_be(ParamTs &&... params)