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

#include <tls_extensions.h>

Inheritance diagram for Botan::TLS::Application_Layer_Protocol_Notification:
Botan::TLS::Extension

Public Member Functions

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

Static Public Member Functions

static Extension_Code static_type ()

Detailed Description

ALPN (RFC 7301)

Definition at line 146 of file tls_extensions.h.

Constructor & Destructor Documentation

◆ Application_Layer_Protocol_Notification() [1/3]

Botan::TLS::Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification ( std::string_view protocol)
explicit

Single protocol, used by server

Definition at line 432 of file tls_extensions.cpp.

432 {
433 BOTAN_ARG_CHECK(!protocol.empty(), "ALPN protocol name must not be empty");
434 BOTAN_ARG_CHECK(protocol.size() < 256, "ALPN protocol name too long");
435 m_protocols.emplace_back(protocol);
436}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33

References BOTAN_ARG_CHECK.

◆ Application_Layer_Protocol_Notification() [2/3]

Botan::TLS::Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification ( std::vector< std::string > protocols)
explicit

List of protocols, used by client

Definition at line 438 of file tls_extensions.cpp.

438 :
439 m_protocols(std::move(protocols)) {
440 for(const auto& protocol : m_protocols) {
441 BOTAN_ARG_CHECK(!protocol.empty(), "ALPN protocol name must not be empty");
442 BOTAN_ARG_CHECK(protocol.size() < 256, "ALPN protocol name too long");
443 }
444}
const std::vector< std::string > & protocols() const

References BOTAN_ARG_CHECK, and protocols().

◆ Application_Layer_Protocol_Notification() [3/3]

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

Definition at line 446 of file tls_extensions.cpp.

448 {
449 if(extension_size < 2) {
450 throw Decoding_Error("ALPN extension cannot be empty");
451 }
452
453 const uint16_t name_bytes = reader.get_uint16_t();
454
455 size_t bytes_remaining = extension_size - 2;
456
457 if(name_bytes != bytes_remaining) {
458 throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
459 }
460
461 // RFC 7301 3.1: ProtocolName protocol_name_list<2..2^16-1>
462 if(name_bytes == 0) {
463 throw Decoding_Error("Empty ALPN protocol_name_list not allowed");
464 }
465
466 while(bytes_remaining > 0) {
467 const std::string p = reader.get_string(1, 0, 255);
468
469 if(bytes_remaining < p.size() + 1) {
470 throw Decoding_Error("Bad encoding of ALPN, length field too long");
471 }
472
473 if(p.empty()) {
474 throw Decoding_Error("Empty ALPN protocol not allowed");
475 }
476
477 bytes_remaining -= (p.size() + 1);
478
479 m_protocols.push_back(p);
480 }
481
482 // RFC 7301 3.1
483 // The "extension_data" field of the [...] extension is structured the
484 // same as described above for the client "extension_data", except that
485 // the "ProtocolNameList" MUST contain exactly one "ProtocolName".
486 if(from == Connection_Side::Server && m_protocols.size() != 1) {
487 throw TLS_Exception(
488 Alert::DecodeError,
489 "Server sent " + std::to_string(m_protocols.size()) + " protocols in ALPN extension response");
490 }
491}

References Botan::TLS::TLS_Data_Reader::get_string(), Botan::TLS::TLS_Data_Reader::get_uint16_t(), and Botan::TLS::Server.

Member Function Documentation

◆ empty()

bool Botan::TLS::Application_Layer_Protocol_Notification::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 170 of file tls_extensions.h.

170{ return m_protocols.empty(); }

◆ 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; }

◆ protocols()

const std::vector< std::string > & Botan::TLS::Application_Layer_Protocol_Notification::protocols ( ) const
inline

Definition at line 152 of file tls_extensions.h.

152{ return m_protocols; }

Referenced by Application_Layer_Protocol_Notification().

◆ serialize()

std::vector< uint8_t > Botan::TLS::Application_Layer_Protocol_Notification::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 498 of file tls_extensions.cpp.

498 {
499 std::vector<uint8_t> buf(2);
500
501 for(auto&& proto : m_protocols) {
502 if(proto.length() >= 256) {
503 throw TLS_Exception(Alert::InternalError, "ALPN name too long");
504 }
505 if(!proto.empty()) {
506 append_tls_length_value(buf, proto, 1);
507 }
508 }
509
510 // RFC 7301 3.1: ProtocolName protocol_name_list<2..2^16-1>;
511 BOTAN_ASSERT_NOMSG(buf.size() - 2 <= 0xFFFF);
512 buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
513 buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
514
515 return buf;
516}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition tls_reader.h:177
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79

References Botan::TLS::append_tls_length_value(), BOTAN_ASSERT_NOMSG, and Botan::get_byte().

◆ single_protocol()

std::string Botan::TLS::Application_Layer_Protocol_Notification::single_protocol ( ) const

Definition at line 493 of file tls_extensions.cpp.

493 {
494 BOTAN_STATE_CHECK(m_protocols.size() == 1);
495 return m_protocols.front();
496}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49

References BOTAN_STATE_CHECK.

◆ static_type()

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

◆ type()

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

Return TLS extension code

Returns
code number of the extension

Implements Botan::TLS::Extension.

Definition at line 150 of file tls_extensions.h.

150{ return static_type(); }

References static_type().


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