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

#include <tls_extensions.h>

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

Public Member Functions

 Certificate_Type_Base (const Certificate_Type_Base &certificate_type_from_client, std::span< const Certificate_Type > server_preference)
 Certificate_Type_Base (std::vector< Certificate_Type > supported_cert_types)
 Certificate_Type_Base (TLS_Data_Reader &reader, uint16_t extension_size, Connection_Side from)
 Client_Certificate_Type (const Client_Certificate_Type &cct, const Policy &policy)
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
Extension_Code type () const override
void validate_selection (const Certificate_Type_Base &from_server) const

Static Public Member Functions

static Extension_Code static_type ()

Detailed Description

Definition at line 216 of file tls_extensions.h.

Constructor & Destructor Documentation

◆ Client_Certificate_Type()

Botan::TLS::Client_Certificate_Type::Client_Certificate_Type ( const Client_Certificate_Type & cct,
const Policy & policy )

Creates the Server Hello extension from the received client preferences.

Definition at line 523 of file tls_extensions.cpp.

523 :
524 Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
Certificate_Type_Base(std::vector< Certificate_Type > supported_cert_types)

References Certificate_Type_Base(), and Client_Certificate_Type().

Referenced by Client_Certificate_Type().

Member Function Documentation

◆ Certificate_Type_Base() [1/3]

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

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

Definition at line 191 of file tls_extensions.cpp.

530 :
532 // RFC 7250 4.2
533 // The server_certificate_type extension in the client hello indicates the
534 // types of certificates the client is able to process when provided by
535 // the server in a subsequent certificate payload. [...] With the
536 // server_certificate_type extension in the server hello, the TLS server
537 // indicates the certificate type carried in the Certificate payload.
538 for(const auto server_supported_cert_type : server_preference) {
539 if(value_exists(certificate_type_from_client.m_certificate_types, server_supported_cert_type)) {
540 m_certificate_types.push_back(server_supported_cert_type);
541 return;
542 }
543 }
544
545 // RFC 7250 4.2 (2.)
546 // The server supports the extension defined in this document, but
547 // it does not have any certificate type in common with the client.
548 // Then, the server terminates the session with a fatal alert of
549 // type "unsupported_certificate".
550 throw TLS_Exception(Alert::UnsupportedCertificate, "Failed to agree on certificate_type");
551}
bool value_exists(const std::vector< T > &vec, const V &val)
Definition stl_util.h:44

◆ Certificate_Type_Base() [2/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 185 of file tls_extensions.cpp.

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

References type().

Referenced by Client_Certificate_Type().

◆ Certificate_Type_Base() [3/3]

Definition at line 195 of file tls_extensions.cpp.

553 :
554 m_from(from) {
555 if(extension_size == 0) {
556 throw Decoding_Error("Certificate type extension cannot be empty");
557 }
558
559 if(from == Connection_Side::Client) {
560 const auto type_bytes = reader.get_tls_length_value(1);
561 if(static_cast<size_t>(extension_size) != type_bytes.size() + 1) {
562 throw Decoding_Error("certificate type extension had inconsistent length");
563 }
564 // RFC 7250 4: {client,server}_certificate_types<1..2^8-1> so must be non-empty
565 if(type_bytes.empty()) {
566 throw Decoding_Error("Certificate type extension contains no types");
567 }
568 std::transform(
569 type_bytes.begin(), type_bytes.end(), std::back_inserter(m_certificate_types), [](const auto type_byte) {
570 return static_cast<Certificate_Type>(type_byte);
571 });
572 } else {
573 // RFC 7250 4.2
574 // Note that only a single value is permitted in the
575 // server_certificate_type extension when carried in the server hello.
576 if(extension_size != 1) {
577 throw Decoding_Error("Server's certificate type extension must be of length 1");
578 }
579 const auto type_byte = reader.get_byte();
580 m_certificate_types.push_back(static_cast<Certificate_Type>(type_byte));
581 }
582}

◆ empty()

bool Botan::TLS::Certificate_Type_Base::empty ( ) const
inlineoverridevirtualinherited

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

202 {
203 // RFC 7250 4.1
204 // If the client has no remaining certificate types to send in the
205 // client hello, other than the default X.509 type, it MUST omit the
206 // entire client[/server]_certificate_type extension [...].
207 return m_from == Connection_Side::Client && m_certificate_types.size() == 1 &&
208 m_certificate_types.front() == Certificate_Type::X509;
209 }

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

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

◆ selected_certificate_type()

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

Definition at line 615 of file tls_extensions.cpp.

615 {
617 BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
618 return m_certificate_types.front();
619}
#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
overridevirtualinherited

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

584 {
585 std::vector<uint8_t> result;
586 if(whoami == Connection_Side::Client) {
587 std::vector<uint8_t> type_bytes;
588 std::transform(
589 m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
590 return static_cast<uint8_t>(type);
591 });
592 append_tls_length_value(result, type_bytes, 1);
593 } else {
594 BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
595 result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
596 }
597 return result;
598}
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:177

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

◆ static_type()

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

Definition at line 225 of file tls_extensions.h.

References Botan::TLS::ClientCertificateType.

Referenced by type().

◆ type()

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

Return TLS extension code

Returns
code number of the extension

Implements Botan::TLS::Extension.

Definition at line 227 of file tls_extensions.h.

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

References static_type().

Referenced by Certificate_Type_Base().

◆ validate_selection()

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

Definition at line 600 of file tls_extensions.cpp.

600 {
602 BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
603
604 // RFC 7250 4.2
605 // The value conveyed in the [client_]certificate_type extension MUST be
606 // selected from one of the values provided in the [client_]certificate_type
607 // extension sent in the client hello.
608 if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
609 throw TLS_Exception(Alert::IllegalParameter,
610 Botan::fmt("Selected certificate type was not offered: {}",
611 certificate_type_to_string(from_server.selected_certificate_type())));
612 }
613}
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: