Botan 3.4.0
Crypto and TLS for C&
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
Botan::TLS::Client_Hello_13 Class Referencefinal

#include <tls_messages.h>

Inheritance diagram for Botan::TLS::Client_Hello_13:
Botan::TLS::Client_Hello Botan::TLS::Handshake_Message

Public Member Functions

std::vector< Signature_Schemecertificate_signature_schemes () const
 
const std::vector< uint16_t > & ciphersuites () 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)
 
const std::vector< uint8_t > & cookie () const
 
std::vector< uint8_t > cookie_input_data () const
 
std::set< Extension_Codeextension_types () const
 
const Extensionsextensions () const
 
std::optional< Protocol_Versionhighest_supported_version (const Policy &policy) const
 
Protocol_Version legacy_version () const
 
std::vector< std::string > next_protocols () const
 
bool offered_suite (uint16_t ciphersuite) const
 
const std::vector< uint8_t > & random () const
 
void retry (const Hello_Retry_Request &hrr, const Transcript_Hash_State &transcript_hash_state, Callbacks &cb, RandomNumberGenerator &rng)
 
bool sent_signature_algorithms () const
 
std::vector< uint8_t > serialize () const override
 
const Session_IDsession_id () const
 
std::vector< Signature_Schemesignature_schemes () const
 
std::string sni_hostname () const
 
std::vector< uint16_t > srtp_profiles () const
 
std::vector< Group_Paramssupported_dh_groups () const
 
std::vector< Group_Paramssupported_ecc_curves () const
 
std::vector< Protocol_Versionsupported_versions () const
 
bool supports_alpn () const
 
Handshake_Type type () const override
 
std::string type_string () const
 
void validate_updates (const Client_Hello_13 &new_ch)
 
virtual Handshake_Type wire_type () const
 

Static Public Member Functions

static std::variant< Client_Hello_13, Client_Hello_12parse (const std::vector< uint8_t > &buf)
 

Protected Member Functions

const std::vector< uint8_t > & compression_methods () const
 

Protected Attributes

std::unique_ptr< Client_Hello_Internal > m_data
 

Detailed Description

Definition at line 218 of file tls_messages.h.

Constructor & Destructor Documentation

◆ Client_Hello_13()

Botan::TLS::Client_Hello_13::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 )

Creates a client hello which might optionally use the passed-in session for resumption. In that case, this will "extract" the master secret from the passed-in session.

Definition at line 728 of file msg_client_hello.cpp.

734 {
735 // RFC 8446 4.1.2
736 // In TLS 1.3, the client indicates its version preferences in the
737 // "supported_versions" extension (Section 4.2.1) and the
738 // legacy_version field MUST be set to 0x0303, which is the version
739 // number for TLS 1.2.
740 m_data->m_legacy_version = Protocol_Version::TLS_V12;
741 m_data->m_random = make_hello_random(rng, cb, policy);
742 m_data->m_suites = policy.ciphersuite_list(Protocol_Version::TLS_V13);
743
744 if(policy.allow_tls12()) // Note: DTLS 1.3 is NYI, hence dtls_12 is not checked
745 {
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());
748 }
749
750 if(policy.tls_13_middlebox_compatibility_mode()) {
751 // RFC 8446 4.1.2
752 // In compatibility mode (see Appendix D.4), this field MUST be non-empty,
753 // so a client not offering a pre-TLS 1.3 session MUST generate a new
754 // 32-byte value.
755 //
756 // Note: we won't ever offer a TLS 1.2 session. In such a case we would
757 // have instantiated a TLS 1.2 client in the first place.
758 m_data->m_session_id = Session_ID(make_hello_random(rng, cb, policy));
759 }
760
761 if(!hostname.empty()) {
762 m_data->extensions().add(new Server_Name_Indicator(hostname));
763 }
764
765 m_data->extensions().add(new Supported_Groups(policy.key_exchange_groups()));
766
767 m_data->extensions().add(new Key_Share(policy, cb, rng));
768
769 m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13, policy));
770
771 m_data->extensions().add(new Signature_Algorithms(policy.acceptable_signature_schemes()));
772 if(auto cert_signing_prefs = policy.acceptable_certificate_signature_schemes()) {
773 // RFC 8446 4.2.3
774 // Implementations which have the same policy in both cases MAY omit
775 // the "signature_algorithms_cert" extension.
776 m_data->extensions().add(new Signature_Algorithms_Cert(std::move(cert_signing_prefs.value())));
777 }
778
779 // TODO: Support for PSK-only mode without a key exchange.
780 // This should be configurable in TLS::Policy and should allow no PSK
781 // support at all (e.g. to disable support for session resumption).
782 m_data->extensions().add(new PSK_Key_Exchange_Modes({PSK_Key_Exchange_Mode::PSK_DHE_KE}));
783
784 if(policy.support_cert_status_message()) {
785 m_data->extensions().add(new Certificate_Status_Request({}, {}));
786 }
787
788 // We currently support "record_size_limit" for TLS 1.3 exclusively. Hence,
789 // when TLS 1.2 is advertised as a supported protocol, we must not offer this
790 // extension.
791 if(policy.record_size_limit().has_value() && !policy.allow_tls12()) {
792 m_data->extensions().add(new Record_Size_Limit(policy.record_size_limit().value()));
793 }
794
795 if(!next_protocols.empty()) {
796 m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocols));
797 }
798
799 // RFC 7250 4.1
800 // In order to indicate the support of raw public keys, clients include
801 // the client_certificate_type and/or the server_certificate_type
802 // extensions in an extended client hello message.
803 m_data->extensions().add(new Client_Certificate_Type(policy.accepted_client_certificate_types()));
804 m_data->extensions().add(new Server_Certificate_Type(policy.accepted_server_certificate_types()));
805
806 if(policy.allow_tls12()) {
807 m_data->extensions().add(new Renegotiation_Extension());
808 m_data->extensions().add(new Session_Ticket_Extension());
809
810 // EMS must always be used with TLS 1.2, regardless of the policy
811 m_data->extensions().add(new Extended_Master_Secret);
812
813 if(policy.negotiate_encrypt_then_mac()) {
814 m_data->extensions().add(new Encrypt_then_MAC);
815 }
816
817 if(m_data->extensions().has<Supported_Groups>() &&
818 !m_data->extensions().get<Supported_Groups>()->ec_groups().empty()) {
819 m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
820 }
821 }
822
823 if(session.has_value() || !psks.empty()) {
824 m_data->extensions().add(new PSK(session, std::move(psks), cb));
825 }
826
827 cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Client, type());
828
829 if(m_data->extensions().has<PSK>()) {
830 // RFC 8446 4.2.11
831 // The "pre_shared_key" extension MUST be the last extension in the
832 // ClientHello (this facilitates implementation [...]).
833 if(m_data->extensions().all().back()->type() != Extension_Code::PresharedKey) {
834 throw TLS_Exception(Alert::InternalError,
835 "Application modified extensions of Client Hello, PSK is not last anymore");
836 }
837 calculate_psk_binders({});
838 }
839}
std::unique_ptr< Client_Hello_Internal > m_data
std::vector< std::string > next_protocols() const
Handshake_Type type() const override
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
Definition tls_session.h:32

References Botan::TLS::Policy::acceptable_certificate_signature_schemes(), Botan::TLS::Policy::acceptable_signature_schemes(), Botan::TLS::Policy::accepted_client_certificate_types(), Botan::TLS::Policy::accepted_server_certificate_types(), Botan::TLS::Policy::allow_tls12(), Botan::TLS::Policy::ciphersuite_list(), Botan::TLS::Client, Botan::TLS::Supported_Groups::ec_groups(), Botan::TLS::Policy::key_exchange_groups(), Botan::TLS::Client_Hello::m_data, Botan::TLS::make_hello_random(), Botan::TLS::Policy::negotiate_encrypt_then_mac(), Botan::TLS::Client_Hello::next_protocols(), Botan::TLS::PresharedKey, Botan::TLS::PSK, Botan::TLS::PSK_DHE_KE, Botan::TLS::Policy::record_size_limit(), Botan::TLS::Policy::support_cert_status_message(), Botan::TLS::Policy::tls_13_middlebox_compatibility_mode(), Botan::TLS::Callbacks::tls_modify_extensions(), Botan::TLS::Client_Hello::type(), and Botan::TLS::Policy::use_ecc_point_compression().

Referenced by parse().

Member Function Documentation

◆ certificate_signature_schemes()

std::vector< Signature_Scheme > Botan::TLS::Client_Hello::certificate_signature_schemes ( ) const
inherited

Definition at line 273 of file msg_client_hello.cpp.

273 {
274 // RFC 8446 4.2.3
275 // If no "signature_algorithms_cert" extension is present, then the
276 // "signature_algorithms" extension also applies to signatures appearing
277 // in certificates.
278 if(Signature_Algorithms_Cert* sigs = m_data->extensions().get<Signature_Algorithms_Cert>()) {
279 return sigs->supported_schemes();
280 } else {
281 return signature_schemes();
282 }
283}
std::vector< Signature_Scheme > signature_schemes() const

References Botan::TLS::Client_Hello::m_data, and Botan::TLS::Client_Hello::signature_schemes().

Referenced by Botan::TLS::Certificate_13::Certificate_13().

◆ ciphersuites()

const std::vector< uint16_t > & Botan::TLS::Client_Hello::ciphersuites ( ) const
inherited

Definition at line 203 of file msg_client_hello.cpp.

203 {
204 return m_data->ciphersuites();
205}

References Botan::TLS::Client_Hello::m_data.

◆ compression_methods()

const std::vector< uint8_t > & Botan::TLS::Client_Hello::compression_methods ( ) const
protectedinherited

Definition at line 199 of file msg_client_hello.cpp.

199 {
200 return m_data->comp_methods();
201}

References Botan::TLS::Client_Hello::m_data.

◆ cookie()

const std::vector< uint8_t > & Botan::TLS::Client_Hello::cookie ( ) const
inherited

Definition at line 390 of file msg_client_hello.cpp.

390 {
391 return m_data->hello_cookie();
392}

References Botan::TLS::Client_Hello::m_data.

◆ cookie_input_data()

std::vector< uint8_t > Botan::TLS::Client_Hello::cookie_input_data ( ) const
inherited

Definition at line 252 of file msg_client_hello.cpp.

252 {
253 BOTAN_STATE_CHECK(!m_data->hello_cookie_input_bits().empty());
254
255 return m_data->hello_cookie_input_bits();
256}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:41

References BOTAN_STATE_CHECK, and Botan::TLS::Client_Hello::m_data.

◆ extension_types()

std::set< Extension_Code > Botan::TLS::Client_Hello::extension_types ( ) const
inherited

Definition at line 207 of file msg_client_hello.cpp.

207 {
208 return m_data->extensions().extension_types();
209}

References Botan::TLS::Client_Hello::m_data.

Referenced by Botan::TLS::Server_Hello_12::Server_Hello_12(), Botan::TLS::Server_Hello_12::Server_Hello_12(), and validate_updates().

◆ extensions()

const Extensions & Botan::TLS::Client_Hello::extensions ( ) const
inherited

◆ highest_supported_version()

std::optional< Protocol_Version > Botan::TLS::Client_Hello_13::highest_supported_version ( const Policy & policy) const

Select the highest protocol version from the list of versions supported by the client. If no such version can be determind this returns std::nullopt.

Definition at line 1019 of file msg_client_hello.cpp.

1019 {
1020 // RFC 8446 4.2.1
1021 // The "supported_versions" extension is used by the client to indicate
1022 // which versions of TLS it supports and by the server to indicate which
1023 // version it is using. The extension contains a list of supported
1024 // versions in preference order, with the most preferred version first.
1025 const auto supvers = m_data->extensions().get<Supported_Versions>();
1026 BOTAN_ASSERT_NONNULL(supvers);
1027
1028 std::optional<Protocol_Version> result;
1029
1030 for(const auto& v : supvers->versions()) {
1031 // RFC 8446 4.2.1
1032 // Servers MUST only select a version of TLS present in that extension
1033 // and MUST ignore any unknown versions that are present in that
1034 // extension.
1035 if(!v.known_version() || !policy.acceptable_protocol_version(v)) {
1036 continue;
1037 }
1038
1039 result = (result.has_value()) ? std::optional(std::max(result.value(), v)) : std::optional(v);
1040 }
1041
1042 return result;
1043}
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86

References Botan::TLS::Policy::acceptable_protocol_version(), BOTAN_ASSERT_NONNULL, and Botan::TLS::Client_Hello::m_data.

◆ legacy_version()

Protocol_Version Botan::TLS::Client_Hello::legacy_version ( ) const
inherited

Return the version indicated in the ClientHello. This may differ from the version indicated in the supported_versions extension.

See RFC 8446 4.1.2: TLS 1.3, the client indicates its version preferences in the "supported_versions" extension (Section 4.2.1) and the legacy_version field MUST be set to 0x0303, which is the version number for TLS 1.2.

Definition at line 187 of file msg_client_hello.cpp.

187 {
188 return m_data->legacy_version();
189}

References Botan::TLS::Client_Hello::m_data.

◆ next_protocols()

std::vector< std::string > Botan::TLS::Client_Hello::next_protocols ( ) const
inherited

Definition at line 376 of file msg_client_hello.cpp.

376 {
377 if(auto alpn = m_data->extensions().get<Application_Layer_Protocol_Notification>()) {
378 return alpn->protocols();
379 }
380 return {};
381}

References Botan::TLS::Client_Hello::m_data.

Referenced by Botan::TLS::Client_Hello_12::Client_Hello_12(), Botan::TLS::Client_Hello_12::Client_Hello_12(), and Client_Hello_13().

◆ offered_suite()

bool Botan::TLS::Client_Hello::offered_suite ( uint16_t ciphersuite) const
inherited

Definition at line 261 of file msg_client_hello.cpp.

261 {
262 return std::find(m_data->ciphersuites().cbegin(), m_data->ciphersuites().cend(), ciphersuite) !=
263 m_data->ciphersuites().cend();
264}

References Botan::TLS::Client_Hello::m_data.

Referenced by Botan::TLS::Client_Hello_12::Client_Hello_12().

◆ parse()

std::variant< Client_Hello_13, Client_Hello_12 > Botan::TLS::Client_Hello_13::parse ( const std::vector< uint8_t > & buf)
static

Definition at line 841 of file msg_client_hello.cpp.

841 {
842 auto data = std::make_unique<Client_Hello_Internal>(buf);
843 const auto version = data->version();
844
845 if(version.is_pre_tls_13()) {
846 return Client_Hello_12(std::move(data));
847 } else {
848 return Client_Hello_13(std::move(data));
849 }
850}
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)

References Client_Hello_13().

◆ random()

const std::vector< uint8_t > & Botan::TLS::Client_Hello::random ( ) const
inherited

Definition at line 191 of file msg_client_hello.cpp.

191 {
192 return m_data->random();
193}

References Botan::TLS::Client_Hello::m_data.

◆ retry()

void Botan::TLS::Client_Hello_13::retry ( const Hello_Retry_Request & hrr,
const Transcript_Hash_State & transcript_hash_state,
Callbacks & cb,
RandomNumberGenerator & rng )

Definition at line 852 of file msg_client_hello.cpp.

855 {
856 BOTAN_STATE_CHECK(m_data->extensions().has<Supported_Groups>());
857 BOTAN_STATE_CHECK(m_data->extensions().has<Key_Share>());
858
859 auto hrr_ks = hrr.extensions().get<Key_Share>();
860 const auto& supported_groups = m_data->extensions().get<Supported_Groups>()->groups();
861
862 if(hrr.extensions().has<Key_Share>()) {
863 m_data->extensions().get<Key_Share>()->retry_offer(*hrr_ks, supported_groups, cb, rng);
864 }
865
866 // RFC 8446 4.2.2
867 // When sending the new ClientHello, the client MUST copy
868 // the contents of the extension received in the HelloRetryRequest into
869 // a "cookie" extension in the new ClientHello.
870 //
871 // RFC 8446 4.2.2
872 // Clients MUST NOT use cookies in their initial ClientHello in subsequent
873 // connections.
874 if(hrr.extensions().has<Cookie>()) {
875 BOTAN_STATE_CHECK(!m_data->extensions().has<Cookie>());
876 m_data->extensions().add(new Cookie(hrr.extensions().get<Cookie>()->get_cookie()));
877 }
878
879 // Note: the consumer of the TLS implementation won't be able to distinguish
880 // invocations to this callback due to the first Client_Hello or the
881 // retried Client_Hello after receiving a Hello_Retry_Request. We assume
882 // that the user keeps and detects this state themselves.
883 cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Client, type());
884
885 auto psk = m_data->extensions().get<PSK>();
886 if(psk) {
887 // Cipher suite should always be a known suite as this is checked upstream
888 const auto cipher = Ciphersuite::by_id(hrr.ciphersuite());
889 BOTAN_ASSERT_NOMSG(cipher.has_value());
890
891 // RFC 8446 4.1.4
892 // In [...] its updated ClientHello, the client SHOULD NOT offer
893 // any pre-shared keys associated with a hash other than that of the
894 // selected cipher suite.
895 psk->filter(cipher.value());
896
897 // RFC 8446 4.2.11.2
898 // If the server responds with a HelloRetryRequest and the client
899 // then sends ClientHello2, its binder will be computed over: [...].
900 calculate_psk_binders(transcript_hash_state.clone());
901 }
902}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
static std::optional< Ciphersuite > by_id(uint16_t suite)

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Botan::TLS::Ciphersuite::by_id(), Botan::TLS::Server_Hello::ciphersuite(), Botan::TLS::Client, Botan::TLS::Transcript_Hash_State::clone(), Botan::TLS::Cookie, Botan::TLS::Server_Hello::extensions(), Botan::TLS::Extensions::get(), Botan::TLS::Cookie::get_cookie(), Botan::TLS::Extensions::has(), Botan::TLS::Client_Hello::m_data, Botan::TLS::Callbacks::tls_modify_extensions(), and Botan::TLS::Client_Hello::type().

◆ sent_signature_algorithms()

bool Botan::TLS::Client_Hello::sent_signature_algorithms ( ) const
inherited

Definition at line 372 of file msg_client_hello.cpp.

372 {
373 return m_data->extensions().has<Signature_Algorithms>();
374}

References Botan::TLS::Client_Hello::m_data.

◆ serialize()

std::vector< uint8_t > Botan::TLS::Client_Hello::serialize ( ) const
overridevirtualinherited
Returns
DER representation of this message

Implements Botan::TLS::Handshake_Message.

Definition at line 224 of file msg_client_hello.cpp.

224 {
225 std::vector<uint8_t> buf;
226 buf.reserve(1024); // working around GCC warning
227
228 buf.push_back(m_data->legacy_version().major_version());
229 buf.push_back(m_data->legacy_version().minor_version());
230 buf += m_data->random();
231
232 append_tls_length_value(buf, m_data->session_id().get(), 1);
233
234 if(m_data->legacy_version().is_datagram_protocol()) {
235 append_tls_length_value(buf, m_data->hello_cookie(), 1);
236 }
237
238 append_tls_length_value(buf, m_data->ciphersuites(), 2);
239 append_tls_length_value(buf, m_data->comp_methods(), 1);
240
241 /*
242 * May not want to send extensions at all in some cases. If so,
243 * should include SCSV value (if reneg info is empty, if not we are
244 * renegotiating with a modern server)
245 */
246
247 buf += m_data->extensions().serialize(Connection_Side::Client);
248
249 return buf;
250}
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition tls_reader.h:180

References Botan::TLS::append_tls_length_value(), Botan::TLS::Client, and Botan::TLS::Client_Hello::m_data.

◆ session_id()

const Session_ID & Botan::TLS::Client_Hello::session_id ( ) const
inherited

Definition at line 195 of file msg_client_hello.cpp.

195 {
196 return m_data->session_id();
197}

References Botan::TLS::Client_Hello::m_data.

Referenced by Botan::TLS::Client_Hello_12::session_handle().

◆ signature_schemes()

std::vector< Signature_Scheme > Botan::TLS::Client_Hello::signature_schemes ( ) const
inherited

Definition at line 266 of file msg_client_hello.cpp.

266 {
267 if(Signature_Algorithms* sigs = m_data->extensions().get<Signature_Algorithms>()) {
268 return sigs->supported_schemes();
269 }
270 return {};
271}

References Botan::TLS::Client_Hello::m_data.

Referenced by Botan::TLS::Certificate_13::Certificate_13(), Botan::TLS::Client_Hello::certificate_signature_schemes(), and Botan::TLS::Handshake_State::choose_sig_format().

◆ sni_hostname()

std::string Botan::TLS::Client_Hello::sni_hostname ( ) const
inherited

Definition at line 306 of file msg_client_hello.cpp.

306 {
307 if(Server_Name_Indicator* sni = m_data->extensions().get<Server_Name_Indicator>()) {
308 return sni->host_name();
309 }
310 return "";
311}

References Botan::TLS::Client_Hello::m_data.

Referenced by Botan::TLS::Certificate_13::Certificate_13(), Botan::TLS::Certificate_Request_13::maybe_create(), and Botan::TLS::Server_Hello_13::Server_Hello_13().

◆ srtp_profiles()

std::vector< uint16_t > Botan::TLS::Client_Hello::srtp_profiles ( ) const
inherited

Definition at line 383 of file msg_client_hello.cpp.

383 {
384 if(SRTP_Protection_Profiles* srtp = m_data->extensions().get<SRTP_Protection_Profiles>()) {
385 return srtp->profiles();
386 }
387 return {};
388}

References Botan::TLS::Client_Hello::m_data.

Referenced by Botan::TLS::Server_Hello_12::Server_Hello_12().

◆ supported_dh_groups()

std::vector< Group_Params > Botan::TLS::Client_Hello::supported_dh_groups ( ) const
inherited

Definition at line 292 of file msg_client_hello.cpp.

292 {
293 if(Supported_Groups* groups = m_data->extensions().get<Supported_Groups>()) {
294 return groups->dh_groups();
295 }
296 return std::vector<Group_Params>();
297}

References Botan::TLS::Client_Hello::m_data.

◆ supported_ecc_curves()

std::vector< Group_Params > Botan::TLS::Client_Hello::supported_ecc_curves ( ) const
inherited

Definition at line 285 of file msg_client_hello.cpp.

285 {
286 if(Supported_Groups* groups = m_data->extensions().get<Supported_Groups>()) {
287 return groups->ec_groups();
288 }
289 return {};
290}

References Botan::TLS::Client_Hello::m_data.

◆ supported_versions()

std::vector< Protocol_Version > Botan::TLS::Client_Hello::supported_versions ( ) const
inherited

Definition at line 324 of file msg_client_hello.cpp.

324 {
325 if(Supported_Versions* versions = m_data->extensions().get<Supported_Versions>()) {
326 return versions->versions();
327 }
328 return {};
329}

References Botan::TLS::Client_Hello::m_data.

◆ supports_alpn()

bool Botan::TLS::Client_Hello::supports_alpn ( ) const
inherited

Definition at line 356 of file msg_client_hello.cpp.

356 {
357 return m_data->extensions().has<Application_Layer_Protocol_Notification>();
358}

References Botan::TLS::Client_Hello::m_data.

Referenced by Botan::TLS::Server_Hello_12::Server_Hello_12(), and Botan::TLS::Server_Hello_12::Server_Hello_12().

◆ type()

Handshake_Type Botan::TLS::Client_Hello::type ( ) const
overridevirtualinherited

◆ type_string()

std::string Botan::TLS::Handshake_Message::type_string ( ) const
inherited
Returns
string representation of this message type

Definition at line 19 of file tls_handshake_state.cpp.

19 {
21}
virtual Handshake_Type type() const =0
const char * handshake_type_to_string(Handshake_Type type)

References Botan::TLS::handshake_type_to_string(), and Botan::TLS::Handshake_Message::type().

◆ validate_updates()

void Botan::TLS::Client_Hello_13::validate_updates ( const Client_Hello_13 & new_ch)

This validates that a Client Hello received after sending a Hello Retry Request was updated in accordance with RFC 8446 4.1.2. If issues are found, this method throws accordingly.

Definition at line 904 of file msg_client_hello.cpp.

904 {
905 // RFC 8446 4.1.2
906 // The client will also send a ClientHello when the server has responded
907 // to its ClientHello with a HelloRetryRequest. In that case, the client
908 // MUST send the same ClientHello without modification, except as follows:
909
910 if(m_data->session_id() != new_ch.m_data->session_id() || m_data->random() != new_ch.m_data->random() ||
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");
914 }
915
916 const auto oldexts = extension_types();
917 const auto newexts = new_ch.extension_types();
918
919 // Check that extension omissions are justified
920 for(const auto oldext : oldexts) {
921 if(!newexts.contains(oldext)) {
922 const auto ext = extensions().get(oldext);
923
924 // We don't make any assumptions about unimplemented extensions.
925 if(!ext->is_implemented()) {
926 continue;
927 }
928
929 // RFC 8446 4.1.2
930 // Removing the "early_data" extension (Section 4.2.10) if one was
931 // present. Early data is not permitted after a HelloRetryRequest.
932 if(oldext == EarlyDataIndication::static_type()) {
933 continue;
934 }
935
936 // RFC 8446 4.1.2
937 // Optionally adding, removing, or changing the length of the
938 // "padding" extension.
939 //
940 // TODO: implement the Padding extension
941 // if(oldext == Padding::static_type())
942 // continue;
943
944 throw TLS_Exception(Alert::IllegalParameter, "Extension removed in updated Client Hello");
945 }
946 }
947
948 // Check that extension additions are justified
949 for(const auto newext : newexts) {
950 if(!oldexts.contains(newext)) {
951 const auto ext = new_ch.extensions().get(newext);
952
953 // We don't make any assumptions about unimplemented extensions.
954 if(!ext->is_implemented()) {
955 continue;
956 }
957
958 // RFC 8446 4.1.2
959 // Including a "cookie" extension if one was provided in the
960 // HelloRetryRequest.
961 if(newext == Cookie::static_type()) {
962 continue;
963 }
964
965 // RFC 8446 4.1.2
966 // Optionally adding, removing, or changing the length of the
967 // "padding" extension.
968 //
969 // TODO: implement the Padding extension
970 // if(newext == Padding::static_type())
971 // continue;
972
973 throw TLS_Exception(Alert::UnsupportedExtension, "Added an extension in updated Client Hello");
974 }
975 }
976
977 // RFC 8446 4.1.2
978 // Removing the "early_data" extension (Section 4.2.10) if one was
979 // present. Early data is not permitted after a HelloRetryRequest.
980 if(new_ch.extensions().has<EarlyDataIndication>()) {
981 throw TLS_Exception(Alert::IllegalParameter, "Updated Client Hello indicates early data");
982 }
983
984 // TODO: Contents of extensions are not checked for update compatibility, see:
985 //
986 // RFC 8446 4.1.2
987 // If a "key_share" extension was supplied in the HelloRetryRequest,
988 // replacing the list of shares with a list containing a single
989 // KeyShareEntry from the indicated group.
990 //
991 // Updating the "pre_shared_key" extension if present by recomputing
992 // the "obfuscated_ticket_age" and binder values and (optionally)
993 // removing any PSKs which are incompatible with the server's
994 // indicated cipher suite.
995 //
996 // Optionally adding, removing, or changing the length of the
997 // "padding" extension.
998}
const Extensions & extensions() const
std::set< Extension_Code > extension_types() const
static Extension_Code static_type()
static Extension_Code static_type()

References Botan::TLS::Client_Hello::extension_types(), Botan::TLS::Client_Hello::extensions(), Botan::TLS::Extensions::get(), Botan::TLS::Extensions::has(), Botan::TLS::Client_Hello::m_data, Botan::TLS::Cookie::static_type(), and Botan::TLS::EarlyDataIndication::static_type().

◆ wire_type()

virtual Handshake_Type Botan::TLS::Handshake_Message::wire_type ( ) const
inlinevirtualinherited
Returns
the wire representation of the message's type

Reimplemented in Botan::TLS::Hello_Retry_Request.

Definition at line 39 of file tls_handshake_msg.h.

39 {
40 // Usually equal to the Handshake_Type enum value,
41 // with the exception of TLS 1.3 Hello Retry Request.
42 return type();
43 }

Referenced by Botan::TLS::Stream_Handshake_IO::send().

Member Data Documentation

◆ m_data

std::unique_ptr<Client_Hello_Internal> Botan::TLS::Client_Hello::m_data
protectedinherited

Definition at line 144 of file tls_messages.h.

Referenced by Botan::TLS::Client_Hello::certificate_signature_schemes(), Botan::TLS::Client_Hello::ciphersuites(), Botan::TLS::Client_Hello::Client_Hello(), Botan::TLS::Client_Hello_12::Client_Hello_12(), Botan::TLS::Client_Hello_12::Client_Hello_12(), Botan::TLS::Client_Hello_12::Client_Hello_12(), Client_Hello_13(), Botan::TLS::Client_Hello::compression_methods(), Botan::TLS::Client_Hello::cookie(), Botan::TLS::Client_Hello::cookie_input_data(), Botan::TLS::Client_Hello::extension_types(), Botan::TLS::Client_Hello::extensions(), highest_supported_version(), Botan::TLS::Client_Hello::legacy_version(), Botan::TLS::Client_Hello::next_protocols(), Botan::TLS::Client_Hello::offered_suite(), Botan::TLS::Client_Hello_12::prefers_compressed_ec_points(), Botan::TLS::Client_Hello::random(), Botan::TLS::Client_Hello_12::renegotiation_info(), retry(), Botan::TLS::Client_Hello_12::secure_renegotiation(), Botan::TLS::Client_Hello::sent_signature_algorithms(), Botan::TLS::Client_Hello::serialize(), Botan::TLS::Client_Hello::session_id(), Botan::TLS::Client_Hello_12::session_ticket(), Botan::TLS::Client_Hello::signature_schemes(), Botan::TLS::Client_Hello::sni_hostname(), Botan::TLS::Client_Hello::srtp_profiles(), Botan::TLS::Client_Hello::supported_dh_groups(), Botan::TLS::Client_Hello::supported_ecc_curves(), Botan::TLS::Client_Hello::supported_versions(), Botan::TLS::Client_Hello::supports_alpn(), Botan::TLS::Client_Hello_12::supports_cert_status_message(), Botan::TLS::Client_Hello_12::supports_encrypt_then_mac(), Botan::TLS::Client_Hello_12::supports_extended_master_secret(), Botan::TLS::Client_Hello_12::supports_session_ticket(), Botan::TLS::Client_Hello_12::update_hello_cookie(), and validate_updates().


The documentation for this class was generated from the following files: