Botan 3.9.0
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)
explicit

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

Definition at line 398 of file tls_extensions.cpp.

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

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 409 of file tls_extensions.cpp.

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

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 433 of file tls_extensions.cpp.

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

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 491 of file tls_extensions.cpp.

491 {
493 BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
494 return m_certificate_types.front();
495}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

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 460 of file tls_extensions.cpp.

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

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 476 of file tls_extensions.cpp.

476 {
478 BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
479
480 // RFC 7250 4.2
481 // The value conveyed in the [client_]certificate_type extension MUST be
482 // selected from one of the values provided in the [client_]certificate_type
483 // extension sent in the client hello.
484 if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
485 throw TLS_Exception(Alert::IllegalParameter,
486 Botan::fmt("Selected certificate type was not offered: {}",
487 certificate_type_to_string(from_server.selected_certificate_type())));
488 }
489}
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: