Botan 3.12.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 108 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 114 of file tls_extensions.h.

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

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

Implements Botan::TLS::Extension.

Definition at line 122 of file tls_extensions.h.

122{ return false; }

◆ host_name()

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

Definition at line 118 of file tls_extensions.h.

118{ 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 407 of file tls_extensions.cpp.

407 {
408 // Avoid sending an IPv4/IPv6 address in SNI as this is prohibited
409
410 if(hostname.empty()) {
411 return false;
412 }
413
414 if(string_to_ipv4(hostname).has_value()) {
415 return false;
416 }
417
418 // IPv6? Anyway ':' is not valid in DNS
419 if(hostname.find(':') != std::string_view::npos) {
420 return false;
421 }
422
423 return true;
424}
std::optional< uint32_t > string_to_ipv4(std::string_view str)
Definition parsing.cpp:155

References Botan::string_to_ipv4().

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
Returns
true if this extension is known and implemented by Botan

Reimplemented in Botan::TLS::Unknown_Extension.

Definition at line 100 of file tls_extensions.h.

100{ return true; }

◆ serialize()

std::vector< uint8_t > Botan::TLS::Server_Name_Indicator::serialize ( Connection_Side whoami) const
overridevirtual
Returns
serialized binary for the extension

Implements Botan::TLS::Extension.

Definition at line 377 of file tls_extensions.cpp.

377 {
378 // RFC 6066
379 // [...] the server SHALL include an extension of type "server_name" in
380 // the (extended) server hello. The "extension_data" field of this
381 // extension SHALL be empty.
382 if(whoami == Connection_Side::Server) {
383 return {};
384 }
385
386 std::vector<uint8_t> buf;
387
388 const size_t name_len = m_sni_host_name.size();
389
390 // RFC 6066 3: HostName<1..2^16-1>; the outer ServerNameList wraps a
391 // 1-byte name_type and a 2-byte length so the whole entry must fit in
392 // a uint16_t too.
393 BOTAN_ASSERT_NOMSG(name_len + 3 <= 0xFFFF);
394
395 buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
396 buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
397 buf.push_back(0); // DNS
398
399 buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
400 buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
401
402 buf += as_span_of_bytes(m_sni_host_name);
403
404 return buf;
405}
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 110 of file tls_extensions.h.

References Botan::TLS::ServerNameIndication.

Referenced by type().

◆ type()

Extension_Code Botan::TLS::Server_Name_Indicator::type ( ) const
inlineoverridevirtual
Returns
code number of the extension

Implements Botan::TLS::Extension.

Definition at line 112 of file tls_extensions.h.

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

References static_type().


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