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/parsing.h>
22#include <botan/internal/stl_util.h>
23#include <botan/internal/tls_handshake_hash.h>
24#include <botan/internal/tls_handshake_io.h>
25#include <botan/internal/tls_reader.h>
26#include <botan/internal/tls_session_key.h>
28#ifdef BOTAN_HAS_TLS_13
29 #include <botan/internal/tls_handshake_layer_13.h>
30 #include <botan/internal/tls_transcript_hash_13.h>
39 auto buf = rng.
random_vec<std::vector<uint8_t>>(32);
51 const uint32_t time32 =
static_cast<uint32_t
>(std::chrono::system_clock::to_time_t(cb.
tls_current_timestamp()));
64class Client_Hello_Internal {
66 Client_Hello_Internal() : m_comp_methods({0}) {}
68 Client_Hello_Internal(
const std::vector<uint8_t>& buf) {
70 throw Decoding_Error(
"Client_Hello: Packet corrupted");
73 TLS_Data_Reader reader(
"ClientHello", buf);
75 const uint8_t major_version = reader.get_byte();
76 const uint8_t minor_version = reader.get_byte();
78 m_legacy_version = Protocol_Version(major_version, minor_version);
79 m_random = reader.get_fixed<uint8_t>(32);
80 m_session_id =
Session_ID(reader.get_range<uint8_t>(1, 0, 32));
84 sha256->update(reader.get_data_read_so_far());
86 m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
88 sha256->update(reader.get_remaining());
89 m_cookie_input_bits = sha256->final_stdvec();
92 m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
93 m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
123 if(!extensions().has<Supported_Versions>() ||
124 !extensions().get<Supported_Versions>()->supports(Protocol_Version::TLS_V13)) {
127 return (m_legacy_version.
is_datagram_protocol()) ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
132 return Protocol_Version::TLS_V13;
137 const Session_ID& session_id()
const {
return m_session_id; }
139 const std::vector<uint8_t>& random()
const {
return m_random; }
141 const std::vector<uint16_t>& ciphersuites()
const {
return m_suites; }
143 const std::vector<uint8_t>& comp_methods()
const {
return m_comp_methods; }
145 const std::vector<uint8_t>& hello_cookie()
const {
return m_hello_cookie; }
147 const std::vector<uint8_t>& hello_cookie_input_bits()
const {
return m_cookie_input_bits; }
149 const Extensions& extensions()
const {
return m_extensions; }
151 Extensions& extensions() {
return m_extensions; }
154 Protocol_Version m_legacy_version;
156 std::vector<uint8_t> m_random;
157 std::vector<uint16_t> m_suites;
158 std::vector<uint8_t> m_comp_methods;
159 Extensions m_extensions;
162 std::vector<uint8_t> m_hello_cookie;
163 std::vector<uint8_t> m_cookie_input_bits;
167Client_Hello& Client_Hello::operator=(Client_Hello&&) noexcept = default;
169Client_Hello::~Client_Hello() = default;
185 return m_data->legacy_version();
193 return m_data->session_id();
197 return m_data->comp_methods();
201 return m_data->ciphersuites();
205 return m_data->extensions().extension_types();
209 return m_data->extensions();
222 std::vector<uint8_t> buf;
225 buf.push_back(
m_data->legacy_version().major_version());
226 buf.push_back(
m_data->legacy_version().minor_version());
231 if(
m_data->legacy_version().is_datagram_protocol()) {
252 return m_data->hello_cookie_input_bits();
259 return std::find(
m_data->ciphersuites().cbegin(),
m_data->ciphersuites().cend(), ciphersuite) !=
260 m_data->ciphersuites().cend();
265 return sigs->supported_schemes();
276 return sigs->supported_schemes();
284 return groups->ec_groups();
291 return groups->dh_groups();
293 return std::vector<Group_Params>();
298 return ecc_formats->prefers_compressed();
305 return sni->host_name();
316 return reneg->renegotiation_info();
323 return versions->versions();
334 return ticket->contents();
346 }
else if(
const auto&
id =
session_id(); !
id.empty()) {
375 return alpn->protocols();
382 return srtp->profiles();
388 return m_data->hello_cookie();
410std::vector<uint8_t> Hello_Request::serialize()
const {
411 return std::vector<uint8_t>();
414void Client_Hello_12::add_tls12_supported_groups_extensions(
const Policy& policy) {
420 const std::vector<Group_Params> kex_groups = policy.key_exchange_groups();
421 std::vector<Group_Params> compatible_kex_groups;
422 std::copy_if(kex_groups.begin(), kex_groups.end(), std::back_inserter(compatible_kex_groups), [](
const auto group) {
423 return !group.is_post_quantum();
426 auto supported_groups = std::make_unique<Supported_Groups>(std::move(compatible_kex_groups));
428 if(!supported_groups->ec_groups().empty()) {
429 m_data->extensions().add(
new Supported_Point_Formats(policy.use_ecc_point_compression()));
432 m_data->extensions().add(std::move(supported_groups));
436 const uint16_t TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF;
438 if(
offered_suite(
static_cast<uint16_t
>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV))) {
440 if(!reneg->renegotiation_info().empty()) {
441 throw TLS_Exception(Alert::HandshakeFailure,
"Client sent renegotiation SCSV and non-empty extension");
453bool hostname_acceptable_for_sni(std::string_view hostname) {
454 if(hostname.empty()) {
463 if(hostname.find(
':') != std::string_view::npos) {
485 const std::vector<uint8_t>& reneg_info,
487 const std::vector<std::string>& next_protocols) {
494 " but our own policy does not accept it");
515 if(hostname_acceptable_for_sni(client_settings.
hostname())) {
523 add_tls12_supported_groups_extensions(policy);
538 if(
m_data->legacy_version().is_datagram_protocol()) {
555 const std::vector<uint8_t>& reneg_info,
557 const std::vector<std::string>& next_protocols) {
571 " but our own policy does not accept it");
598 if(hostname_acceptable_for_sni(hostname)) {
606 add_tls12_supported_groups_extensions(policy);
626#if defined(BOTAN_HAS_TLS_13)
643 if(
m_data->legacy_version().is_tls_13_or_later()) {
644 throw TLS_Exception(Alert::DecodeError,
"TLS 1.3 Client Hello has invalid legacy_version");
652 if(
m_data->comp_methods().size() != 1 ||
m_data->comp_methods().front() != 0) {
653 throw TLS_Exception(Alert::IllegalParameter,
"Client did not offer NULL compression");
661 if(exts.has<
PSK>()) {
662 if(!exts.has<PSK_Key_Exchange_Modes>()) {
663 throw TLS_Exception(Alert::MissingExtension,
664 "Client Hello offered a PSK without a psk_key_exchange_modes extension");
672 throw TLS_Exception(Alert::IllegalParameter,
"PSK extension was not at the very end of the Client Hello");
690 if(!exts.has<
PSK>()) {
691 if(!exts.has<Supported_Groups>() || !exts.has<Signature_Algorithms>()) {
693 Alert::MissingExtension,
694 "Non-PSK Client Hello did not contain supported_groups and signature_algorithms extensions");
697 if(exts.has<Supported_Groups>() != exts.has<Key_Share>()) {
698 throw TLS_Exception(Alert::MissingExtension,
699 "Client Hello must either contain both key_share and supported_groups extensions or neither");
702 if(exts.has<Key_Share>()) {
703 const auto supported_ext = exts.get<Supported_Groups>();
705 const auto supports = supported_ext->groups();
706 const auto offers = exts.get<Key_Share>()->offered_groups();
717 auto found_in_supported_groups = [&supports, support_offset = -1](
auto group)
mutable {
718 const auto i = std::find(supports.begin(), supports.end(), group);
719 if(i == supports.end()) {
723 const auto found_at = std::distance(supports.begin(), i);
724 if(found_at <= support_offset) {
729 support_offset =
static_cast<decltype(support_offset)
>(found_at);
733 for(
const auto offered : offers) {
737 if(!found_in_supported_groups(offered)) {
738 throw TLS_Exception(Alert::IllegalParameter,
739 "Offered key exchange groups do not align with claimed supported groups");
756 std::string_view hostname,
757 const std::vector<std::string>& next_protocols,
758 std::optional<Session_with_Handle>& session,
759 std::vector<ExternalPSK> psks) {
765 m_data->m_legacy_version = Protocol_Version::TLS_V12;
771 const auto legacy_suites = policy.
ciphersuite_list(Protocol_Version::TLS_V12);
772 m_data->m_suites.insert(
m_data->m_suites.end(), legacy_suites.cbegin(), legacy_suites.cend());
786 if(hostname_acceptable_for_sni(hostname)) {
848 if(session.has_value() || !psks.empty()) {
849 m_data->extensions().add(
new PSK(session, std::move(psks), cb));
860 "Application modified extensions of Client Hello, PSK is not last anymore");
862 calculate_psk_binders({});
867 auto data = std::make_unique<Client_Hello_Internal>(buf);
868 const auto version = data->version();
870 if(version.is_pre_tls_13()) {
888 m_data->extensions().get<
Key_Share>()->retry_offer(*hrr_ks, supported_groups, cb, rng);
910 auto psk =
m_data->extensions().get<
PSK>();
920 psk->filter(cipher.value());
925 calculate_psk_binders(transcript_hash_state.
clone());
936 m_data->ciphersuites() != new_ch.
m_data->ciphersuites() ||
937 m_data->comp_methods() != new_ch.
m_data->comp_methods()) {
938 throw TLS_Exception(Alert::IllegalParameter,
"Client Hello core values changed after Hello Retry Request");
945 for(
const auto oldext : oldexts) {
946 if(!newexts.contains(oldext)) {
950 if(!ext->is_implemented()) {
969 throw TLS_Exception(Alert::IllegalParameter,
"Extension removed in updated Client Hello");
974 for(
const auto newext : newexts) {
975 if(!oldexts.contains(newext)) {
979 if(!ext->is_implemented()) {
998 throw TLS_Exception(Alert::UnsupportedExtension,
"Added an extension in updated Client Hello");
1006 throw TLS_Exception(Alert::IllegalParameter,
"Updated Client Hello indicates early data");
1026 auto psk =
m_data->extensions().get<
PSK>();
1027 if(!psk || psk->empty()) {
1041 psk->calculate_binders(ths);
1053 std::optional<Protocol_Version> result;
1055 for(
const auto& v : supvers->versions()) {
1064 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
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
std::optional< uint32_t > string_to_ipv4(std::string_view str)
bool value_exists(const std::vector< T > &vec, const OT &val)
constexpr auto store_be(ParamTs &&... params)