Botan 3.12.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 (const std::vector< std::string > &protocols)
 Application_Layer_Protocol_Notification (std::string_view protocol)
 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 133 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 426 of file tls_extensions.cpp.

426 {
427 BOTAN_ARG_CHECK(!protocol.empty(), "ALPN protocol name must not be empty");
428 BOTAN_ARG_CHECK(protocol.size() < 256, "ALPN protocol name too long");
429 m_protocols.emplace_back(protocol);
430}
#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 ( const std::vector< std::string > & protocols)
explicit

List of protocols, used by client

Definition at line 432 of file tls_extensions.cpp.

433 :
434 m_protocols(protocols) {
435 for(const auto& protocol : protocols) {
436 BOTAN_ARG_CHECK(!protocol.empty(), "ALPN protocol name must not be empty");
437 BOTAN_ARG_CHECK(protocol.size() < 256, "ALPN protocol name too long");
438 }
439}
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 441 of file tls_extensions.cpp.

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

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
Returns
if we should encode this extension or not

Implements Botan::TLS::Extension.

Definition at line 157 of file tls_extensions.h.

157{ return m_protocols.empty(); }

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

◆ protocols()

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

Definition at line 139 of file tls_extensions.h.

139{ 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
Returns
serialized binary for the extension

Implements Botan::TLS::Extension.

Definition at line 493 of file tls_extensions.cpp.

493 {
494 std::vector<uint8_t> buf(2);
495
496 for(auto&& proto : m_protocols) {
497 if(proto.length() >= 256) {
498 throw TLS_Exception(Alert::InternalError, "ALPN name too long");
499 }
500 if(!proto.empty()) {
501 append_tls_length_value(buf, proto, 1);
502 }
503 }
504
505 // RFC 7301 3.1: ProtocolName protocol_name_list<2..2^16-1>;
506 BOTAN_ASSERT_NOMSG(buf.size() - 2 <= 0xFFFF);
507 buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
508 buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
509
510 return buf;
511}
#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 488 of file tls_extensions.cpp.

488 {
489 BOTAN_STATE_CHECK(m_protocols.size() == 1);
490 return m_protocols.front();
491}
#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
Returns
code number of the extension

Implements Botan::TLS::Extension.

Definition at line 137 of file tls_extensions.h.

137{ return static_type(); }

References static_type().


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