Botan 3.9.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 907 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 996 of file tls_extensions.h.

996 {
997 deserialize(reader, side, message_type);
998 }
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 931 of file tls_extensions.h.

931{ 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 121 of file tls_extensions.cpp.

121 {
122 if(has(extn->type())) {
123 throw Invalid_Argument("cannot add the same extension twice: " +
124 std::to_string(static_cast<uint16_t>(extn->type())));
125 }
126
127 m_extensions.emplace_back(extn.release());
128}

References has().

Referenced by deserialize().

◆ all()

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

Definition at line 911 of file tls_extensions.h.

911{ 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 952 of file tls_extensions.h.

952 {
953 return contains_other_than(allowed_extensions, true);
954 }
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 158 of file tls_extensions.cpp.

159 {
160 const auto found = extension_types();
161
162 std::vector<Extension_Code> diff;
163 std::set_difference(
164 found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
165
166 if(allow_unknown_extensions) {
167 // Go through the found unexpected extensions whether any of those
168 // is known to this TLS implementation.
169 const auto itr = std::find_if(diff.cbegin(), diff.cend(), [this](const auto ext_type) {
170 const auto ext = get(ext_type);
171 return ext && ext->is_implemented();
172 });
173
174 // ... if yes, `contains_other_than` is true
175 return itr != diff.cend();
176 }
177
178 return !diff.empty();
179}
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 130 of file tls_extensions.cpp.

130 {
131 if(reader.has_remaining()) {
132 const uint16_t all_extn_size = reader.get_uint16_t();
133
134 if(reader.remaining_bytes() != all_extn_size) {
135 throw Decoding_Error("Bad extension size");
136 }
137
138 while(reader.has_remaining()) {
139 const uint16_t extension_code = reader.get_uint16_t();
140 const uint16_t extension_size = reader.get_uint16_t();
141
142 const auto type = static_cast<Extension_Code>(extension_code);
143
144 if(this->has(type)) {
145 throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
146 }
147
148 // TODO offer a function on reader that returns a byte range as a reference
149 // to avoid this copy of the extension data
150 const std::vector<uint8_t> extn_data = reader.get_fixed<uint8_t>(extension_size);
151 TLS_Data_Reader extn_reader("Extension", extn_data);
152 this->add(make_extension(extn_reader, type, from, message_type));
153 extn_reader.assert_done();
154 }
155 }
156}

References add(), Botan::TLS::TLS_Data_Reader::get_fixed(), 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 927 of file tls_extensions.h.

927{ return m_extensions.empty(); }

◆ extension_types()

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

Definition at line 228 of file tls_extensions.cpp.

228 {
229 std::set<Extension_Code> offers;
230 std::transform(
231 m_extensions.cbegin(), m_extensions.cend(), std::inserter(offers, offers.begin()), [](const auto& ext) {
232 return ext->type();
233 });
234 return offers;
235}

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 114 of file tls_extensions.cpp.

114 {
115 const auto i =
116 std::find_if(m_extensions.cbegin(), m_extensions.cend(), [type](const auto& ext) { return ext->type() == type; });
117
118 return (i != m_extensions.end()) ? i->get() : nullptr;
119}

◆ 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 923 of file tls_extensions.h.

923{ 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 987 of file tls_extensions.h.

987{ 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 194 of file tls_extensions.cpp.

194 {
195 std::vector<uint8_t> buf(2); // 2 bytes for length field
196
197 for(const auto& extn : m_extensions) {
198 if(extn->empty()) {
199 continue;
200 }
201
202 const uint16_t extn_code = static_cast<uint16_t>(extn->type());
203
204 const std::vector<uint8_t> extn_val = extn->serialize(whoami);
205
206 buf.push_back(get_byte<0>(extn_code));
207 buf.push_back(get_byte<1>(extn_code));
208
209 buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
210 buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
211
212 buf += extn_val;
213 }
214
215 const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
216
217 buf[0] = get_byte<0>(extn_size);
218 buf[1] = get_byte<1>(extn_size);
219
220 // avoid sending a completely empty extensions block
221 if(buf.size() == 2) {
222 return std::vector<uint8_t>();
223 }
224
225 return buf;
226}
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 925 of file tls_extensions.h.

925{ 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 961 of file tls_extensions.h.

961 {
962 std::unique_ptr<T> out_ptr;
963
964 auto ext = take(T::static_type());
965 if(ext != nullptr) {
966 out_ptr.reset(dynamic_cast<T*>(ext.get()));
967 BOTAN_ASSERT_NOMSG(out_ptr != nullptr);
968 ext.release();
969 }
970
971 return out_ptr;
972 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
constexpr auto out_ptr(T &outptr) noexcept
Definition stl_util.h:415

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 181 of file tls_extensions.cpp.

181 {
182 const auto i =
183 std::find_if(m_extensions.begin(), m_extensions.end(), [type](const auto& ext) { return ext->type() == type; });
184
185 std::unique_ptr<Extension> result;
186 if(i != m_extensions.end()) {
187 std::swap(result, *i);
188 m_extensions.erase(i);
189 }
190
191 return result;
192}

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