Botan 3.0.0
Crypto and TLS for C&
Public Member Functions | List of all members
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, const bool allow_unknown_extensions=false) const
 
void deserialize (TLS_Data_Reader &reader, const Connection_Side from, const Handshake_Type message_type)
 
std::set< Extension_Codeextension_types () const
 
 Extensions ()=default
 
 Extensions (Extensions &&)=default
 
 Extensions (TLS_Data_Reader &reader, Connection_Side side, Handshake_Type message_type)
 
template<typename T >
Tget () const
 
Extensionget (Extension_Code type) const
 
template<typename T >
bool has () const
 
bool has (Extension_Code type) const
 
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)
 

Detailed Description

Represents a block of extensions in a hello message

Definition at line 835 of file tls_extensions.h.

Constructor & Destructor Documentation

◆ Extensions() [1/3]

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

◆ Extensions() [2/3]

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

◆ Extensions() [3/3]

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

Definition at line 949 of file tls_extensions.h.

950 {
951 deserialize(reader, side, message_type);
952 }
void deserialize(TLS_Data_Reader &reader, const Connection_Side from, const Handshake_Type message_type)

Member Function Documentation

◆ add() [1/2]

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

Definition at line 869 of file tls_extensions.h.

870 {
871 add(std::unique_ptr<Extension>(extn));
872 }
void add(std::unique_ptr< Extension > extn)

◆ add() [2/2]

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

Definition at line 103 of file tls_extensions.cpp.

104 {
105 if (has(extn->type()))
106 {
107 throw Invalid_Argument("cannot add the same extension twice: " +
108 std::to_string(static_cast<uint16_t>(extn->type())));
109 }
110
111 m_extensions.emplace_back(extn.release());
112 }

References has().

Referenced by deserialize().

◆ all()

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

Definition at line 840 of file tls_extensions.h.

841 {
842 return m_extensions;
843 }

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

904 {
905 return contains_other_than(allowed_extensions, true);
906 }
bool contains_other_than(const std::set< Extension_Code > &allowed_extensions, const bool allow_unknown_extensions=false) const

◆ contains_other_than()

bool Botan::TLS::Extensions::contains_other_than ( const std::set< Extension_Code > &  allowed_extensions,
const 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 148 of file tls_extensions.cpp.

150 {
151 const auto found = extension_types();
152
153 std::vector<Extension_Code> diff;
154 std::set_difference(found.cbegin(), found.end(),
155 allowed_extensions.cbegin(), allowed_extensions.cend(),
156 std::back_inserter(diff));
157
158 if(allow_unknown_extensions)
159 {
160 // Go through the found unexpected extensions whether any of those
161 // is known to this TLS implementation.
162 const auto itr = std::find_if(diff.cbegin(), diff.cend(),
163 [this](const auto ext_type)
164 {
165 const auto ext = get(ext_type);
166 return ext && ext->is_implemented();
167 });
168
169 // ... if yes, `contains_other_than` is true
170 return itr != diff.cend();
171 }
172
173 return !diff.empty();
174 }
std::set< Extension_Code > extension_types() const

References extension_types().

◆ deserialize()

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

Definition at line 114 of file tls_extensions.cpp.

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

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().

◆ extension_types()

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

Definition at line 227 of file tls_extensions.cpp.

228 {
229 std::set<Extension_Code> offers;
230 std::transform(m_extensions.cbegin(), m_extensions.cend(),
231 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

Definition at line 846 of file tls_extensions.h.

847 {
848 return dynamic_cast<T*>(get(T::static_type()));
849 }
FE_25519 T
Definition: ge.cpp:36

References T.

◆ get() [2/2]

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

Definition at line 874 of file tls_extensions.h.

875 {
876 const auto i = std::find_if(m_extensions.cbegin(), m_extensions.cend(),
877 [type](const auto &ext) {
878 return ext->type() == type;
879 });
880
881 return (i != m_extensions.end()) ? i->get() : nullptr;
882 }

◆ has() [1/2]

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

Definition at line 852 of file tls_extensions.h.

853 {
854 return get<T>() != nullptr;
855 }

Referenced by add(), and deserialize().

◆ has() [2/2]

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

Definition at line 857 of file tls_extensions.h.

858 {
859 return get(type) != nullptr;
860 }

◆ operator=()

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

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

941 {
942 return take(type) != nullptr;
943 }
decltype(auto) take()

◆ serialize()

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

Definition at line 193 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 {
199 if(extn->empty())
200 continue;
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 return buf;
225 }

◆ size()

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

Definition at line 862 of file tls_extensions.h.

863 {
864 return m_extensions.size();
865 }

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

914 {
915 std::unique_ptr<T> out_ptr;
916
917 auto ext = take(T::static_type());
918 if (ext != nullptr) {
919 out_ptr.reset(dynamic_cast<T*>(ext.get()));
920 BOTAN_ASSERT_NOMSG(out_ptr != nullptr);
921 ext.release();
922 }
923
924 return out_ptr;
925 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:67

References BOTAN_ASSERT_NOMSG, and T.

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

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

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