Botan 3.5.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 214 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 387 of file tls_extensions.cpp.

387 :
388 m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
389 BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
390}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29

References BOTAN_ARG_CHECK.

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

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

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

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

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

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

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

116{ return true; }

◆ selected_certificate_type()

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

Definition at line 480 of file tls_extensions.cpp.

480 {
482 BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
483 return m_certificate_types.front();
484}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59

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

449 {
450 std::vector<uint8_t> result;
451 if(whoami == Connection_Side::Client) {
452 std::vector<uint8_t> type_bytes;
453 std::transform(
454 m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
455 return static_cast<uint8_t>(type);
456 });
457 append_tls_length_value(result, type_bytes, 1);
458 } else {
459 BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
460 result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
461 }
462 return result;
463}
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 465 of file tls_extensions.cpp.

465 {
467 BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
468
469 // RFC 7250 4.2
470 // The value conveyed in the [client_]certificate_type extension MUST be
471 // selected from one of the values provided in the [client_]certificate_type
472 // extension sent in the client hello.
473 if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
474 throw TLS_Exception(Alert::IllegalParameter,
475 Botan::fmt("Selected certificate type was not offered: {}",
476 certificate_type_to_string(from_server.selected_certificate_type())));
477 }
478}
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, 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: