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

#include <tls_extensions.h>

Public Member Functions

void add (Extension *extn)
void add (std::unique_ptr< Extension > extn)
const std::vector< std::unique_ptr< Extension > > & all () const
bool contains_implemented_extensions_other_than (const std::set< Extension_Code > &allowed_extensions) const
bool contains_other_than (const std::set< Extension_Code > &allowed_extensions, bool allow_unknown_extensions=false) const
void deserialize (TLS_Data_Reader &reader, Connection_Side from, Handshake_Type message_type)
bool empty () const
std::set< Extension_Codeextension_types () const
 Extensions ()=default
 Extensions (const Extensions &)=delete
 Extensions (Extensions &&)=default
 Extensions (TLS_Data_Reader &reader, Connection_Side side, Handshake_Type message_type)
template<typename T>
T * get () const
Extensionget (Extension_Code type) const
template<typename T>
bool has () const
bool has (Extension_Code type) const
Extensionsoperator= (const Extensions &)=delete
Extensionsoperator= (Extensions &&)=default
bool remove_extension (Extension_Code type)
std::vector< uint8_t > serialize (Connection_Side whoami) const
size_t size () const
template<typename T>
decltype(auto) take ()
std::unique_ptr< Extensiontake (Extension_Code type)
 ~Extensions ()

Detailed Description

Represents a block of extensions in a hello message

Definition at line 457 of file tls_extensions.h.

Constructor & Destructor Documentation

◆ Extensions() [1/4]

Botan::TLS::Extensions::Extensions ( )
default

◆ Extensions() [2/4]

Botan::TLS::Extensions::Extensions ( const Extensions & )
delete

References Extensions().

◆ Extensions() [3/4]

Botan::TLS::Extensions::Extensions ( Extensions && )
default

References Extensions().

◆ ~Extensions()

Botan::TLS::Extensions::~Extensions ( )
default

◆ Extensions() [4/4]

Botan::TLS::Extensions::Extensions ( TLS_Data_Reader & reader,
Connection_Side side,
Handshake_Type message_type )
inline

Definition at line 546 of file tls_extensions.h.

546 {
547 deserialize(reader, side, message_type);
548 }
void deserialize(TLS_Data_Reader &reader, Connection_Side from, Handshake_Type message_type)

References deserialize().

Member Function Documentation

◆ add() [1/2]

void Botan::TLS::Extensions::add ( Extension * extn)
inline

Definition at line 481 of file tls_extensions.h.

481{ add(std::unique_ptr<Extension>(extn)); }
void add(std::unique_ptr< Extension > extn)

References add().

Referenced by add().

◆ add() [2/2]

void Botan::TLS::Extensions::add ( std::unique_ptr< Extension > extn)

Definition at line 143 of file tls_extensions.cpp.

143 {
144 if(has(extn->type())) {
145 throw Invalid_Argument("cannot add the same extension twice: " +
146 std::to_string(static_cast<uint16_t>(extn->type())));
147 }
148
149 m_extensions.emplace_back(extn.release());
150}

References has().

◆ all()

const std::vector< std::unique_ptr< Extension > > & Botan::TLS::Extensions::all ( ) const
inline

Definition at line 461 of file tls_extensions.h.

461{ return m_extensions; }

◆ contains_implemented_extensions_other_than()

bool Botan::TLS::Extensions::contains_implemented_extensions_other_than ( const std::set< Extension_Code > & allowed_extensions) const
inline
Parameters
allowed_extensionsextension types that are allowed
Returns
true if this contains any extensions implemented by Botan that are not contained in allowed_extensions.

Definition at line 502 of file tls_extensions.h.

502 {
503 return contains_other_than(allowed_extensions, true);
504 }
bool contains_other_than(const std::set< Extension_Code > &allowed_extensions, bool allow_unknown_extensions=false) const

References contains_other_than().

◆ contains_other_than()

bool Botan::TLS::Extensions::contains_other_than ( const std::set< Extension_Code > & allowed_extensions,
bool allow_unknown_extensions = false ) const
Parameters
allowed_extensionsextension types that are allowed
allow_unknown_extensionsif true, ignores unrecognized extensions
Returns
true if this contains any extensions that are not contained in allowed_extensions.

Definition at line 180 of file tls_extensions.cpp.

181 {
182 const auto found = extension_types();
183
184 std::vector<Extension_Code> diff;
185 std::set_difference(
186 found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
187
188 if(allow_unknown_extensions) {
189 // Go through the found unexpected extensions whether any of those
190 // is known to this TLS implementation.
191 const auto itr = std::find_if(diff.cbegin(), diff.cend(), [this](const auto ext_type) {
192 const auto ext = get(ext_type);
193 return ext && ext->is_implemented();
194 });
195
196 // ... if yes, `contains_other_than` is true
197 return itr != diff.cend();
198 }
199
200 return !diff.empty();
201}
std::set< Extension_Code > extension_types() const

References extension_types().

Referenced by contains_implemented_extensions_other_than().

◆ deserialize()

void Botan::TLS::Extensions::deserialize ( TLS_Data_Reader & reader,
Connection_Side from,
Handshake_Type message_type )

Definition at line 152 of file tls_extensions.cpp.

152 {
153 if(reader.has_remaining()) {
154 const uint16_t all_extn_size = reader.get_uint16_t();
155
156 if(reader.remaining_bytes() != all_extn_size) {
157 throw Decoding_Error("Bad extension size");
158 }
159
160 while(reader.has_remaining()) {
161 const uint16_t extension_code = reader.get_uint16_t();
162 const uint16_t extension_size = reader.get_uint16_t();
163
164 const auto type = static_cast<Extension_Code>(extension_code);
165
166 if(this->has(type)) {
167 throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
168 }
169
170 // TODO offer a function on reader that returns a byte range as a reference
171 // to avoid this copy of the extension data
172 const std::vector<uint8_t> extn_data = reader.get_fixed<uint8_t>(extension_size);
173 TLS_Data_Reader extn_reader("Extension", extn_data);
174 this->add(make_extension(extn_reader, type, from, message_type));
175 extn_reader.assert_done();
176 }
177 }
178}

References Botan::TLS::TLS_Data_Reader::get_uint16_t(), has(), Botan::TLS::TLS_Data_Reader::has_remaining(), and Botan::TLS::TLS_Data_Reader::remaining_bytes().

Referenced by Extensions().

◆ empty()

bool Botan::TLS::Extensions::empty ( ) const
inline

Definition at line 477 of file tls_extensions.h.

477{ return m_extensions.empty(); }

◆ extension_types()

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

Definition at line 250 of file tls_extensions.cpp.

250 {
251 std::set<Extension_Code> offers;
252 std::transform(
253 m_extensions.cbegin(), m_extensions.cend(), std::inserter(offers, offers.begin()), [](const auto& ext) {
254 return ext->type();
255 });
256 return offers;
257}

Referenced by contains_other_than().

◆ get() [1/2]

template<typename T>
T * Botan::TLS::Extensions::get ( ) const
inline

◆ get() [2/2]

Extension * Botan::TLS::Extensions::get ( Extension_Code type) const

Definition at line 136 of file tls_extensions.cpp.

136 {
137 const auto i =
138 std::find_if(m_extensions.cbegin(), m_extensions.cend(), [type](const auto& ext) { return ext->type() == type; });
139
140 return (i != m_extensions.end()) ? i->get() : nullptr;
141}

◆ has() [1/2]

template<typename T>
bool Botan::TLS::Extensions::has ( ) const
inline

◆ has() [2/2]

bool Botan::TLS::Extensions::has ( Extension_Code type) const
inline

Definition at line 473 of file tls_extensions.h.

473{ return get(type) != nullptr; }

References get().

◆ operator=() [1/2]

Extensions & Botan::TLS::Extensions::operator= ( const Extensions & )
delete

References Extensions().

◆ operator=() [2/2]

Extensions & Botan::TLS::Extensions::operator= ( Extensions && )
default

References Extensions().

◆ remove_extension()

bool Botan::TLS::Extensions::remove_extension ( Extension_Code type)
inline

Remove an extension from this extensions object, if it exists. Returns true if the extension existed (and thus is now removed), otherwise false (the extension wasn't set in the first place).

Note: not used internally, might be used in Callbacks::tls_modify_extensions()

Definition at line 537 of file tls_extensions.h.

537{ return take(type) != nullptr; }
decltype(auto) take()

References take().

◆ serialize()

std::vector< uint8_t > Botan::TLS::Extensions::serialize ( Connection_Side whoami) const

Definition at line 216 of file tls_extensions.cpp.

216 {
217 std::vector<uint8_t> buf(2); // 2 bytes for length field
218
219 for(const auto& extn : m_extensions) {
220 if(extn->empty()) {
221 continue;
222 }
223
224 const uint16_t extn_code = static_cast<uint16_t>(extn->type());
225
226 const std::vector<uint8_t> extn_val = extn->serialize(whoami);
227
228 buf.push_back(get_byte<0>(extn_code));
229 buf.push_back(get_byte<1>(extn_code));
230
231 buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
232 buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
233
234 buf += extn_val;
235 }
236
237 const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
238
239 buf[0] = get_byte<0>(extn_size);
240 buf[1] = get_byte<1>(extn_size);
241
242 // avoid sending a completely empty extensions block
243 if(buf.size() == 2) {
244 return std::vector<uint8_t>();
245 }
246
247 return buf;
248}
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79

References Botan::get_byte().

◆ size()

size_t Botan::TLS::Extensions::size ( ) const
inline

Definition at line 475 of file tls_extensions.h.

475{ return m_extensions.size(); }

◆ take() [1/2]

template<typename T>
decltype(auto) Botan::TLS::Extensions::take ( )
inline

Take the extension with the given type out of the extensions list. Returns a nullptr if the extension didn't exist.

Definition at line 511 of file tls_extensions.h.

511 {
512 std::unique_ptr<T> out_ptr;
513
514 auto ext = take(T::static_type());
515 if(ext != nullptr) {
516 out_ptr.reset(dynamic_cast<T*>(ext.get()));
517 BOTAN_ASSERT_NOMSG(out_ptr != nullptr);
518 ext.release();
519 }
520
521 return out_ptr;
522 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
constexpr auto out_ptr(T &outptr) noexcept
Definition stl_util.h:127

References BOTAN_ASSERT_NOMSG, Botan::out_ptr(), and take().

Referenced by remove_extension(), and take().

◆ take() [2/2]

std::unique_ptr< Extension > Botan::TLS::Extensions::take ( Extension_Code type)

Take the extension with the given type out of the extensions list. Returns a nullptr if the extension didn't exist.

Definition at line 203 of file tls_extensions.cpp.

203 {
204 const auto i =
205 std::find_if(m_extensions.begin(), m_extensions.end(), [type](const auto& ext) { return ext->type() == type; });
206
207 std::unique_ptr<Extension> result;
208 if(i != m_extensions.end()) {
209 std::swap(result, *i);
210 m_extensions.erase(i);
211 }
212
213 return result;
214}

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