Botan 3.8.1
Crypto and TLS for C&
Botan::TLS::Certificate_Type_Base Class Referenceabstract

#include <tls_extensions.h>

Inheritance diagram for Botan::TLS::Certificate_Type_Base:
Botan::TLS::Extension Botan::TLS::Client_Certificate_Type Botan::TLS::Server_Certificate_Type

Public Member Functions

 Certificate_Type_Base (std::vector< Certificate_Type > supported_cert_types)
 
 Certificate_Type_Base (TLS_Data_Reader &reader, uint16_t extension_size, Connection_Side from)
 
bool empty () const override
 
virtual bool is_implemented () const
 
Certificate_Type selected_certificate_type () const
 
std::vector< uint8_t > serialize (Connection_Side whoami) const override
 
virtual Extension_Code type () const =0
 
void validate_selection (const Certificate_Type_Base &from_server) const
 

Protected Member Functions

 Certificate_Type_Base (const Certificate_Type_Base &certificate_type_from_client, const std::vector< Certificate_Type > &server_preference)
 

Detailed Description

RFC 7250 Base class for 'client_certificate_type' and 'server_certificate_type' extensions.

Definition at line 213 of file tls_extensions.h.

Constructor & Destructor Documentation

◆ Certificate_Type_Base() [1/3]

Botan::TLS::Certificate_Type_Base::Certificate_Type_Base ( std::vector< Certificate_Type > supported_cert_types)

Called by the client to advertise support for a number of cert types.

Definition at line 395 of file tls_extensions.cpp.

395 :
396 m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
397 BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
398}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:31

References BOTAN_ARG_CHECK.

Referenced by Certificate_Type_Base(), and validate_selection().

◆ Certificate_Type_Base() [2/3]

Botan::TLS::Certificate_Type_Base::Certificate_Type_Base ( const Certificate_Type_Base & certificate_type_from_client,
const std::vector< Certificate_Type > & server_preference )
protected

Called by the server to select a cert type to be used in the handshake.

Definition at line 406 of file tls_extensions.cpp.

407 :
409 // RFC 7250 4.2
410 // The server_certificate_type extension in the client hello indicates the
411 // types of certificates the client is able to process when provided by
412 // the server in a subsequent certificate payload. [...] With the
413 // server_certificate_type extension in the server hello, the TLS server
414 // indicates the certificate type carried in the Certificate payload.
415 for(const auto server_supported_cert_type : server_preference) {
416 if(value_exists(certificate_type_from_client.m_certificate_types, server_supported_cert_type)) {
417 m_certificate_types.push_back(server_supported_cert_type);
418 return;
419 }
420 }
421
422 // RFC 7250 4.2 (2.)
423 // The server supports the extension defined in this document, but
424 // it does not have any certificate type in common with the client.
425 // Then, the server terminates the session with a fatal alert of
426 // type "unsupported_certificate".
427 throw TLS_Exception(Alert::UnsupportedCertificate, "Failed to agree on certificate_type");
428}
bool value_exists(const std::vector< T > &vec, const OT &val)
Definition stl_util.h:61

References Certificate_Type_Base(), and Botan::value_exists().

◆ Certificate_Type_Base() [3/3]

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

Definition at line 430 of file tls_extensions.cpp.

430 :
431 m_from(from) {
432 if(extension_size == 0) {
433 throw Decoding_Error("Certificate type extension cannot be empty");
434 }
435
436 if(from == Connection_Side::Client) {
437 const auto type_bytes = reader.get_tls_length_value(1);
438 if(static_cast<size_t>(extension_size) != type_bytes.size() + 1) {
439 throw Decoding_Error("certificate type extension had inconsistent length");
440 }
441 std::transform(
442 type_bytes.begin(), type_bytes.end(), std::back_inserter(m_certificate_types), [](const auto type_byte) {
443 return static_cast<Certificate_Type>(type_byte);
444 });
445 } else {
446 // RFC 7250 4.2
447 // Note that only a single value is permitted in the
448 // server_certificate_type extension when carried in the server hello.
449 if(extension_size != 1) {
450 throw Decoding_Error("Server's certificate type extension must be of length 1");
451 }
452 const auto type_byte = reader.get_byte();
453 m_certificate_types.push_back(static_cast<Certificate_Type>(type_byte));
454 }
455}

References Botan::TLS::Client, Botan::TLS::TLS_Data_Reader::get_byte(), and Botan::TLS::TLS_Data_Reader::get_tls_length_value().

Member Function Documentation

◆ empty()

bool Botan::TLS::Certificate_Type_Base::empty ( ) const
inlineoverridevirtual
Returns
if we should encode this extension or not

Implements Botan::TLS::Extension.

Definition at line 235 of file tls_extensions.h.

235 {
236 // RFC 7250 4.1
237 // If the client has no remaining certificate types to send in the
238 // client hello, other than the default X.509 type, it MUST omit the
239 // entire client[/server]_certificate_type extension [...].
240 return m_from == Connection_Side::Client && m_certificate_types.size() == 1 &&
241 m_certificate_types.front() == Certificate_Type::X509;
242 }

References Botan::TLS::Client, and Botan::TLS::X509.

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

115{ return true; }

◆ selected_certificate_type()

Certificate_Type Botan::TLS::Certificate_Type_Base::selected_certificate_type ( ) const

Definition at line 488 of file tls_extensions.cpp.

488 {
490 BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
491 return m_certificate_types.front();
492}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:61

References BOTAN_ASSERT_NOMSG, and Botan::TLS::Server.

Referenced by validate_selection().

◆ serialize()

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

Implements Botan::TLS::Extension.

Definition at line 457 of file tls_extensions.cpp.

457 {
458 std::vector<uint8_t> result;
459 if(whoami == Connection_Side::Client) {
460 std::vector<uint8_t> type_bytes;
461 std::transform(
462 m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
463 return static_cast<uint8_t>(type);
464 });
465 append_tls_length_value(result, type_bytes, 1);
466 } else {
467 BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
468 result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
469 }
470 return result;
471}
virtual Extension_Code type() const =0
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:180

References Botan::TLS::append_tls_length_value(), BOTAN_ASSERT_NOMSG, Botan::TLS::Client, and Botan::TLS::Extension::type().

◆ type()

◆ validate_selection()

void Botan::TLS::Certificate_Type_Base::validate_selection ( const Certificate_Type_Base & from_server) const

Definition at line 473 of file tls_extensions.cpp.

473 {
475 BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
476
477 // RFC 7250 4.2
478 // The value conveyed in the [client_]certificate_type extension MUST be
479 // selected from one of the values provided in the [client_]certificate_type
480 // extension sent in the client hello.
481 if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
482 throw TLS_Exception(Alert::IllegalParameter,
483 Botan::fmt("Selected certificate type was not offered: {}",
484 certificate_type_to_string(from_server.selected_certificate_type())));
485 }
486}
std::string certificate_type_to_string(Certificate_Type type)
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53

References BOTAN_ASSERT_NOMSG, Certificate_Type_Base(), Botan::TLS::certificate_type_to_string(), Botan::TLS::Client, Botan::fmt(), selected_certificate_type(), Botan::TLS::Server, and Botan::value_exists().


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