Botan 3.11.0
Crypto and TLS for C&
Botan::TLS::Hello_Retry_Request Class Referencefinal

#include <tls_messages_13.h>

Inheritance diagram for Botan::TLS::Hello_Retry_Request:
Botan::TLS::Server_Hello_13 Botan::TLS::Server_Hello Botan::TLS::Handshake_Message

Public Member Functions

uint16_t ciphersuite () const
const Extensionsextensions () const
std::optional< Protocol_Versionrandom_signals_downgrade () const
Protocol_Version selected_version () const final
std::vector< uint8_t > serialize () const override
const Session_IDsession_id () const
Handshake_Type type () const override
std::string type_string () const
Handshake_Type wire_type () const override

Static Public Member Functions

static std::variant< Hello_Retry_Request, Server_Hello_13create (const Client_Hello_13 &ch, bool hello_retry_request_allowed, Session_Manager &session_mgr, Credentials_Manager &credentials_mgr, RandomNumberGenerator &rng, const Policy &policy, Callbacks &cb)
static std::variant< Hello_Retry_Request, Server_Hello_13, Server_Hello_12_Shimparse (const std::vector< uint8_t > &buf)

Protected Member Functions

void basic_validation () const
uint8_t compression_method () const
std::set< Extension_Codeextension_types () const
 Hello_Retry_Request (const Client_Hello_13 &ch, Named_Group selected_group, const Policy &policy, Callbacks &cb)
 Hello_Retry_Request (std::unique_ptr< Server_Hello_Internal > data)
Protocol_Version legacy_version () const
const std::vector< uint8_t > & random () const

Protected Attributes

std::unique_ptr< Server_Hello_Internalm_data

Static Protected Attributes

static const struct Botan::TLS::Server_Hello_13::Hello_Retry_Request_Tag as_hello_retry_request
static const struct Botan::TLS::Server_Hello_13::Hello_Retry_Request_Creation_Tag as_new_hello_retry_request
static const struct Botan::TLS::Server_Hello_13::Server_Hello_Tag as_server_hello

Friends

class Server_Hello_13

Detailed Description

Definition at line 134 of file tls_messages_13.h.

Constructor & Destructor Documentation

◆ Hello_Retry_Request() [1/2]

Botan::TLS::Hello_Retry_Request::Hello_Retry_Request ( std::unique_ptr< Server_Hello_Internal > data)
explicitprotected

Definition at line 356 of file msg_server_hello_13.cpp.

356 :
static const struct Botan::TLS::Server_Hello_13::Hello_Retry_Request_Tag as_hello_retry_request

References Botan::TLS::Server_Hello_13::as_hello_retry_request, Hello_Retry_Request(), and Server_Hello_13.

Referenced by Hello_Retry_Request(), and Server_Hello_13.

◆ Hello_Retry_Request() [2/2]

Botan::TLS::Hello_Retry_Request::Hello_Retry_Request ( const Client_Hello_13 & ch,
Named_Group selected_group,
const Policy & policy,
Callbacks & cb )
protected

Definition at line 359 of file msg_server_hello_13.cpp.

362 :
363 Server_Hello_13(std::make_unique<Server_Hello_Internal>(
364 Protocol_Version::TLS_V12 /* legacy_version */,
365 ch.session_id(),
366 std::vector<uint8_t>(HELLO_RETRY_REQUEST_MARKER.begin(), HELLO_RETRY_REQUEST_MARKER.end()),
367 choose_ciphersuite(ch, policy),
368 uint8_t(0) /* compression method */,
369 true /* is Hello Retry Request */
370 ),
372 // RFC 8446 4.1.4
373 // As with the ServerHello, a HelloRetryRequest MUST NOT contain any
374 // extensions that were not first offered by the client in its
375 // ClientHello, with the exception of optionally the "cookie" [...]
376 // extension.
377 BOTAN_STATE_CHECK(ch.extensions().has<Supported_Groups>());
378 BOTAN_STATE_CHECK(ch.extensions().has<Key_Share>());
379
380 BOTAN_STATE_CHECK(!value_exists(ch.extensions().get<Key_Share>()->offered_groups(), selected_group));
381
382 // RFC 8446 4.1.4
383 // The server's extensions MUST contain "supported_versions".
384 //
385 // RFC 8446 4.2.1
386 // A server which negotiates TLS 1.3 MUST respond by sending a
387 // "supported_versions" extension containing the selected version
388 // value (0x0304). It MUST set the ServerHello.legacy_version field to
389 // 0x0303 (TLS 1.2).
390 //
391 // Note that the legacy version (TLS 1.2) is set in this constructor's
392 // initializer list, accordingly.
393 // NOLINTBEGIN(*-owning-memory)
394 m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13));
395
396 m_data->extensions().add(new Key_Share(selected_group));
397 // NOLINTEND(*-owning-memory)
398
399 cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
400}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
Handshake_Type type() const override
static const struct Botan::TLS::Server_Hello_13::Hello_Retry_Request_Creation_Tag as_new_hello_retry_request
std::unique_ptr< Server_Hello_Internal > m_data
constexpr std::array< uint8_t, 32 > HELLO_RETRY_REQUEST_MARKER
Definition tls_magic.h:126
bool value_exists(const std::vector< T > &vec, const V &val)
Definition stl_util.h:43

References Botan::TLS::Server_Hello_13::as_new_hello_retry_request, BOTAN_STATE_CHECK, Botan::TLS::Client_Hello::extensions(), Botan::TLS::Extensions::get(), Botan::TLS::Extensions::has(), Botan::TLS::HELLO_RETRY_REQUEST_MARKER, Botan::TLS::Server_Hello::m_data, Botan::TLS::Key_Share::offered_groups(), Botan::TLS::Server, Server_Hello_13, Botan::TLS::Server_Hello::session_id(), Botan::TLS::Callbacks::tls_modify_extensions(), type(), and Botan::value_exists().

Member Function Documentation

◆ basic_validation()

void Botan::TLS::Server_Hello_13::basic_validation ( ) const
protectedinherited

Validation that applies to both Server Hello and Hello Retry Request

Definition at line 109 of file msg_server_hello_13.cpp.

109 {
110 BOTAN_ASSERT_NOMSG(m_data->version() == Protocol_Version::TLS_V13);
111
112 // Note: checks that cannot be performed without contextual information
113 // are done in the specific TLS client implementation.
114 // Note: The Supported_Version extension makes sure internally that
115 // exactly one entry is provided.
116
117 // Note: Hello Retry Request basic validation is equivalent with the
118 // basic validations required for Server Hello
119 //
120 // RFC 8446 4.1.4
121 // Upon receipt of a HelloRetryRequest, the client MUST check the
122 // legacy_version, [...], and legacy_compression_method as specified in
123 // Section 4.1.3 and then process the extensions, starting with determining
124 // the version using "supported_versions".
125
126 // RFC 8446 4.1.3
127 // In TLS 1.3, [...] the legacy_version field MUST be set to 0x0303
128 if(legacy_version() != Protocol_Version::TLS_V12) {
129 throw TLS_Exception(Alert::ProtocolVersion,
130 "legacy_version '" + legacy_version().to_string() + "' is not allowed");
131 }
132
133 // RFC 8446 4.1.3
134 // legacy_compression_method: A single byte which MUST have the value 0.
135 if(compression_method() != 0x00) {
136 throw TLS_Exception(Alert::DecodeError, "compression is not supported in TLS 1.3");
137 }
138
139 // RFC 8446 4.1.3
140 // All TLS 1.3 ServerHello messages MUST contain the "supported_versions" extension.
141 if(!extensions().has<Supported_Versions>()) {
142 throw TLS_Exception(Alert::MissingExtension, "server hello did not contain 'supported version' extension");
143 }
144
145 // RFC 8446 4.2.1
146 // A server which negotiates TLS 1.3 MUST respond by sending
147 // a "supported_versions" extension containing the selected version
148 // value (0x0304).
149 if(selected_version() != Protocol_Version::TLS_V13) {
150 throw TLS_Exception(Alert::IllegalParameter, "TLS 1.3 Server Hello selected a different version");
151 }
152}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
Protocol_Version selected_version() const final
const Extensions & extensions() const
Protocol_Version legacy_version() const
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition exceptn.cpp:13

References BOTAN_ASSERT_NOMSG, Botan::TLS::Server_Hello::compression_method(), Botan::TLS::Server_Hello::extensions(), Botan::TLS::Server_Hello::legacy_version(), Botan::TLS::Server_Hello::m_data, selected_version(), and Botan::to_string().

Referenced by Server_Hello_13(), and Server_Hello_13().

◆ ciphersuite()

uint16_t Botan::TLS::Server_Hello::ciphersuite ( ) const
inherited

Definition at line 145 of file msg_server_hello.cpp.

145 {
146 return m_data->ciphersuite();
147}

References m_data.

Referenced by Botan::TLS::Client_Hello_13::retry(), Botan::TLS::Server_Hello_12::Server_Hello_12(), and ~Server_Hello().

◆ compression_method()

uint8_t Botan::TLS::Server_Hello::compression_method ( ) const
protectedinherited

Definition at line 137 of file msg_server_hello.cpp.

137 {
138 return m_data->comp_method();
139}

References m_data.

Referenced by Botan::TLS::Server_Hello_13::basic_validation(), and selected_version().

◆ create()

std::variant< Hello_Retry_Request, Server_Hello_13 > Botan::TLS::Server_Hello_13::create ( const Client_Hello_13 & ch,
bool hello_retry_request_allowed,
Session_Manager & session_mgr,
Credentials_Manager & credentials_mgr,
RandomNumberGenerator & rng,
const Policy & policy,
Callbacks & cb )
staticinherited

Definition at line 28 of file msg_server_hello_13.cpp.

34 {
35 const auto& exts = ch.extensions();
36
37 // RFC 8446 4.2.9
38 // [With PSK with (EC)DHE key establishment], the client and server MUST
39 // supply "key_share" values [...].
40 //
41 // Note: We currently do not support PSK without (EC)DHE, hence, we can
42 // assume that those extensions are available.
43 BOTAN_ASSERT_NOMSG(exts.has<Supported_Groups>() && exts.has<Key_Share>());
44 const auto& supported_by_client = exts.get<Supported_Groups>()->groups();
45 const auto& offered_by_client = exts.get<Key_Share>()->offered_groups();
46 const auto selected_group = policy.choose_key_exchange_group(supported_by_client, offered_by_client);
47
48 // RFC 8446 4.1.1
49 // If there is no overlap between the received "supported_groups" and the
50 // groups supported by the server, then the server MUST abort the
51 // handshake with a "handshake_failure" or an "insufficient_security" alert.
52 if(selected_group == Named_Group::NONE) {
53 throw TLS_Exception(Alert::HandshakeFailure, "Client did not offer any acceptable group");
54 }
55
56 // RFC 8446 4.2.8:
57 // Servers MUST NOT send a KeyShareEntry for any group not indicated in the
58 // client's "supported_groups" extension [...]
59 if(!value_exists(supported_by_client, selected_group)) {
60 throw TLS_Exception(Alert::InternalError, "Application selected a group that is not supported by the client");
61 }
62
63 // RFC 8446 4.1.4
64 // The server will send this message in response to a ClientHello
65 // message if it is able to find an acceptable set of parameters but the
66 // ClientHello does not contain sufficient information to proceed with
67 // the handshake.
68 //
69 // In this case, the Client Hello did not contain a key share offer for
70 // the group selected by the application.
71 if(!value_exists(offered_by_client, selected_group)) {
72 // RFC 8446 4.1.4
73 // If a client receives a second HelloRetryRequest in the same
74 // connection (i.e., where the ClientHello was itself in response to a
75 // HelloRetryRequest), it MUST abort the handshake with an
76 // "unexpected_message" alert.
77 BOTAN_STATE_CHECK(hello_retry_request_allowed);
78 return Hello_Retry_Request(ch, selected_group, policy, cb);
79 } else {
80 return Server_Hello_13(ch, selected_group, session_mgr, credentials_mgr, rng, cb, policy);
81 }
82}
Server_Hello_13(std::unique_ptr< Server_Hello_Internal > data, Server_Hello_Tag tag=as_server_hello)

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Botan::TLS::Policy::choose_key_exchange_group(), Botan::TLS::Client_Hello::extensions(), Server_Hello_13(), and Botan::value_exists().

◆ extension_types()

std::set< Extension_Code > Botan::TLS::Server_Hello::extension_types ( ) const
protectedinherited

Definition at line 149 of file msg_server_hello.cpp.

149 {
150 return m_data->extensions().extension_types();
151}

References m_data.

Referenced by selected_version().

◆ extensions()

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

◆ legacy_version()

Protocol_Version Botan::TLS::Server_Hello::legacy_version ( ) const
protectedinherited

Definition at line 129 of file msg_server_hello.cpp.

129 {
130 return m_data->legacy_version();
131}

References m_data.

Referenced by Botan::TLS::Server_Hello_13::basic_validation(), selected_version(), and Botan::TLS::Server_Hello_12_Shim::selected_version().

◆ parse()

std::variant< Hello_Retry_Request, Server_Hello_13, Server_Hello_12_Shim > Botan::TLS::Server_Hello_13::parse ( const std::vector< uint8_t > & buf)
staticinherited

Definition at line 84 of file msg_server_hello_13.cpp.

85 {
86 auto data = std::make_unique<Server_Hello_Internal>(buf);
87 const auto version = data->version();
88
89 // server hello that appears to be pre-TLS 1.3, takes precedence over...
90 if(version.is_pre_tls_13()) {
91 return Server_Hello_12_Shim(std::move(data));
92 }
93
94 // ... the TLS 1.3 "special case" aka. Hello_Retry_Request
95 if(version == Protocol_Version::TLS_V13) {
96 if(data->is_hello_retry_request()) {
97 return Hello_Retry_Request(std::move(data));
98 }
99
100 return Server_Hello_13(std::move(data));
101 }
102
103 throw TLS_Exception(Alert::ProtocolVersion, "unexpected server hello version: " + version.to_string());
104}

References Server_Hello_13().

◆ random()

const std::vector< uint8_t > & Botan::TLS::Server_Hello::random ( ) const
protectedinherited

Definition at line 133 of file msg_server_hello.cpp.

133 {
134 return m_data->random();
135}

References m_data.

Referenced by selected_version().

◆ random_signals_downgrade()

std::optional< Protocol_Version > Botan::TLS::Server_Hello_13::random_signals_downgrade ( ) const
inherited

Return desired downgrade version indicated by hello random, if any.

Definition at line 336 of file msg_server_hello_13.cpp.

336 {
337 const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
338 if(last8 == DOWNGRADE_TLS11) {
339 return Protocol_Version::TLS_V11;
340 }
341 if(last8 == DOWNGRADE_TLS12) {
342 return Protocol_Version::TLS_V12;
343 }
344
345 return std::nullopt;
346}
constexpr uint64_t DOWNGRADE_TLS12
Definition tls_magic.h:118
constexpr uint64_t DOWNGRADE_TLS11
Definition tls_magic.h:107
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504

References Botan::TLS::DOWNGRADE_TLS11, Botan::TLS::DOWNGRADE_TLS12, Botan::load_be(), Botan::TLS::Server_Hello::m_data, and random_signals_downgrade().

Referenced by random_signals_downgrade().

◆ selected_version()

Protocol_Version Botan::TLS::Server_Hello_13::selected_version ( ) const
finalvirtualinherited
Returns
the selected version as indicated by the supported_versions extension

Implements Botan::TLS::Server_Hello.

Definition at line 348 of file msg_server_hello_13.cpp.

348 {
349 auto* const versions_ext = m_data->extensions().get<Supported_Versions>();
350 BOTAN_ASSERT_NOMSG(versions_ext);
351 const auto& versions = versions_ext->versions();
352 BOTAN_ASSERT_NOMSG(versions.size() == 1);
353 return versions.front();
354}

References BOTAN_ASSERT_NOMSG, Botan::TLS::Server_Hello::m_data, and selected_version().

Referenced by basic_validation(), and selected_version().

◆ serialize()

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

Implements Botan::TLS::Handshake_Message.

Definition at line 105 of file msg_server_hello.cpp.

105 {
106 std::vector<uint8_t> buf;
107 buf.reserve(1024); // working around GCC warning
108
109 buf.push_back(m_data->legacy_version().major_version());
110 buf.push_back(m_data->legacy_version().minor_version());
111 buf += m_data->random();
112
113 append_tls_length_value(buf, m_data->session_id().get(), 1);
114
115 buf.push_back(get_byte<0>(m_data->ciphersuite()));
116 buf.push_back(get_byte<1>(m_data->ciphersuite()));
117
118 buf.push_back(m_data->comp_method());
119
120 buf += m_data->extensions().serialize(Connection_Side::Server);
121
122 return buf;
123}
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:177
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79

References Botan::TLS::append_tls_length_value(), Botan::get_byte(), m_data, serialize(), Botan::TLS::Server, and Server_Hello().

Referenced by serialize(), and ~Server_Hello().

◆ session_id()

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

◆ type()

Handshake_Type Botan::TLS::Hello_Retry_Request::type ( ) const
inlineoverridevirtual
Returns
the message type

Implements Botan::TLS::Handshake_Message.

Definition at line 141 of file tls_messages_13.h.

References Botan::TLS::HelloRetryRequest.

Referenced by Hello_Retry_Request().

◆ type_string()

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

Definition at line 21 of file tls_handshake_state.cpp.

21 {
23}
virtual Handshake_Type type() const =0
const char * handshake_type_to_string(Handshake_Type type)
Definition tls_magic.cpp:15

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

◆ wire_type()

Handshake_Type Botan::TLS::Hello_Retry_Request::wire_type ( ) const
inlineoverridevirtual
Returns
the wire representation of the message's type

Reimplemented from Botan::TLS::Handshake_Message.

Definition at line 143 of file tls_messages_13.h.

References Botan::TLS::ServerHello.

◆ Server_Hello_13

friend class Server_Hello_13
friend

Member Data Documentation

◆ as_hello_retry_request

const Server_Hello_13::Hello_Retry_Request_Tag Botan::TLS::Server_Hello_13::as_hello_retry_request
staticprotectedinherited

◆ as_new_hello_retry_request

const Server_Hello_13::Hello_Retry_Request_Creation_Tag Botan::TLS::Server_Hello_13::as_new_hello_retry_request
staticprotectedinherited

◆ as_server_hello

const Server_Hello_13::Server_Hello_Tag Botan::TLS::Server_Hello_13::as_server_hello
staticprotectedinherited

Definition at line 24 of file msg_server_hello_13.cpp.

◆ m_data


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