Botan 3.13.0
Crypto and TLS for C&
Botan::TLS::Server_Name_Indicator Class Referencefinal

#include <tls_extensions.h>

Inheritance diagram for Botan::TLS::Server_Name_Indicator:
Botan::TLS::Extension

Public Member Functions

bool empty () const override
std::string host_name () const
virtual bool is_implemented () const
std::vector< uint8_t > serialize (Connection_Side whoami) const override
 Server_Name_Indicator (std::string_view host_name)
 Server_Name_Indicator (TLS_Data_Reader &reader, uint16_t extension_size, Connection_Side from)
Extension_Code type () const override

Static Public Member Functions

static bool hostname_acceptable_for_sni (std::string_view hostname)
static Extension_Code static_type ()

Detailed Description

Server Name Indicator extension (RFC 3546)

Definition at line 121 of file tls_extensions.h.

Constructor & Destructor Documentation

◆ Server_Name_Indicator() [1/2]

Botan::TLS::Server_Name_Indicator::Server_Name_Indicator ( std::string_view host_name)
inlineexplicit

Definition at line 127 of file tls_extensions.h.

127: m_sni_host_name(host_name) {}

References host_name().

◆ Server_Name_Indicator() [2/2]

Botan::TLS::Server_Name_Indicator::Server_Name_Indicator ( TLS_Data_Reader & reader,
uint16_t extension_size,
Connection_Side from )

Definition at line 320 of file tls_extensions.cpp.

320 {
321 /*
322 RFC 6066 Section 3
323
324 A server that receives a client hello containing the "server_name"
325 extension MAY use the information contained in the extension to guide
326 its selection of an appropriate certificate to return to the client,
327 and/or other aspects of security policy. In this event, the server
328 SHALL include an extension of type "server_name" in the (extended)
329 server hello. The "extension_data" field of this extension SHALL be
330 empty.
331 */
332 if(from == Connection_Side::Server) {
333 if(extension_size != 0) {
334 throw TLS_Exception(Alert::IllegalParameter, "Server sent non-empty SNI extension");
335 }
336 } else {
337 // Clients are required to send at least one name in the SNI
338 if(extension_size == 0) {
339 throw TLS_Exception(Alert::IllegalParameter, "Client sent empty SNI extension");
340 }
341
342 const uint16_t name_bytes = reader.get_uint16_t();
343
344 // RFC 6066 3: a ServerName carrying a host_name (the only NameType
345 // currently defined and the only one this implementation acts on)
346 // requires at least 1 byte name_type + 2 byte length + 1 byte HostName.
347 if(name_bytes + 2 != extension_size || name_bytes < 4) {
348 throw Decoding_Error("Bad encoding of SNI extension");
349 }
350
351 BOTAN_ASSERT_NOMSG(reader.remaining_bytes() == name_bytes);
352
353 while(reader.has_remaining()) {
354 const uint8_t name_type = reader.get_byte();
355
356 if(name_type == 0) {
357 /*
358 RFC 6066 Section 3
359 The ServerNameList MUST NOT contain more than one name of the same name_type.
360 */
361 if(!m_sni_host_name.empty()) {
362 throw Decoding_Error("TLS ServerNameIndicator contains more than one host_name");
363 }
364 m_sni_host_name = reader.get_string(2, 1, 65535);
365 } else {
366 /*
367 Unknown name type - skip its length-prefixed value and continue
368
369 RFC 6066 Section 3
370 For backward compatibility, all future data structures associated
371 with new NameTypes MUST begin with a 16-bit length field.
372 */
373 const uint16_t unknown_name_len = reader.get_uint16_t();
374 reader.discard_next(unknown_name_len);
375 }
376 }
377 }
378}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG, Botan::TLS::TLS_Data_Reader::discard_next(), Botan::TLS::TLS_Data_Reader::get_byte(), Botan::TLS::TLS_Data_Reader::get_string(), Botan::TLS::TLS_Data_Reader::get_uint16_t(), Botan::TLS::TLS_Data_Reader::has_remaining(), Botan::TLS::TLS_Data_Reader::remaining_bytes(), and Botan::TLS::Server.

Member Function Documentation

◆ empty()

bool Botan::TLS::Server_Name_Indicator::empty ( ) const
inlineoverridevirtual

Predicate if a TLS extension should be included or not

Returns
true if this extension should be encoded, otherwise false

Implements Botan::TLS::Extension.

Definition at line 135 of file tls_extensions.h.

135{ return false; }

◆ host_name()

std::string Botan::TLS::Server_Name_Indicator::host_name ( ) const
inline

Definition at line 131 of file tls_extensions.h.

131{ return m_sni_host_name; }

Referenced by Server_Name_Indicator().

◆ hostname_acceptable_for_sni()

bool Botan::TLS::Server_Name_Indicator::hostname_acceptable_for_sni ( std::string_view hostname)
static

Definition at line 410 of file tls_extensions.cpp.

410 {
411 // Avoid sending an IPv4/IPv6 address in SNI as this is prohibited
412
413 if(hostname.empty() || hostname.size() > 255) {
414 return false;
415 }
416
417 if(auto ipv4 = IPv4Address::from_string(hostname)) {
418 return false;
419 }
420
421 if(auto ipv6 = IPv6Address::from_string(hostname)) {
422 return false;
423 }
424
425 if(auto dns = DNSName::from_string(hostname)) {
426 return true;
427 } else {
428 return false;
429 }
430}
static std::optional< DNSName > from_string(std::string_view name)
Definition dns_name.cpp:136
static std::optional< IPv4Address > from_string(std::string_view str)
static std::optional< IPv6Address > from_string(std::string_view str)

References Botan::DNSName::from_string(), Botan::IPv4Address::from_string(), and Botan::IPv6Address::from_string().

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

◆ is_implemented()

virtual bool Botan::TLS::Extension::is_implemented ( ) const
inlinevirtualinherited

Predicate if the extension is known/implemented

Note
this exists primarily to support unknown extension handling and doesn't need to be overridden even in the custom extension case.
Returns
true if this extension is known

Reimplemented in Botan::TLS::Unknown_Extension.

Definition at line 113 of file tls_extensions.h.

113{ return true; }

◆ serialize()

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

Serialize a TLS extension

Parameters
whoamiwhich peer we are acting as in the protocol
Returns
serialized binary for the extension

Implements Botan::TLS::Extension.

Definition at line 380 of file tls_extensions.cpp.

380 {
381 // RFC 6066
382 // [...] the server SHALL include an extension of type "server_name" in
383 // the (extended) server hello. The "extension_data" field of this
384 // extension SHALL be empty.
385 if(whoami == Connection_Side::Server) {
386 return {};
387 }
388
389 std::vector<uint8_t> buf;
390
391 const size_t name_len = m_sni_host_name.size();
392
393 // RFC 6066 3: HostName<1..2^16-1>; the outer ServerNameList wraps a
394 // 1-byte name_type and a 2-byte length so the whole entry must fit in
395 // a uint16_t too.
396 BOTAN_ASSERT_NOMSG(name_len + 3 <= 0xFFFF);
397
398 buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
399 buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
400 buf.push_back(0); // DNS
401
402 buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
403 buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
404
405 buf += as_span_of_bytes(m_sni_host_name);
406
407 return buf;
408}
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79
std::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)
Definition mem_utils.h:59

References Botan::as_span_of_bytes(), BOTAN_ASSERT_NOMSG, Botan::get_byte(), and Botan::TLS::Server.

◆ static_type()

Extension_Code Botan::TLS::Server_Name_Indicator::static_type ( )
inlinestatic

Definition at line 123 of file tls_extensions.h.

References Botan::TLS::ServerNameIndication.

Referenced by type().

◆ type()

Extension_Code Botan::TLS::Server_Name_Indicator::type ( ) const
inlineoverridevirtual

Return TLS extension code

Returns
code number of the extension

Implements Botan::TLS::Extension.

Definition at line 125 of file tls_extensions.h.

125{ return static_type(); }
static Extension_Code static_type()

References static_type().


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