Botan 3.11.1
Crypto and TLS for C&
Botan::TLS::Stream_Handshake_IO Class Referencefinal

#include <tls_handshake_io.h>

Inheritance diagram for Botan::TLS::Stream_Handshake_IO:
Botan::TLS::Handshake_IO

Public Types

typedef std::function< void(Record_Type, const std::vector< uint8_t > &)> writer_fn

Public Member Functions

void add_record (const uint8_t record[], size_t record_len, Record_Type type, uint64_t sequence_number) override
std::vector< uint8_t > format (const std::vector< uint8_t > &handshake_msg, Handshake_Type handshake_type) const override
std::pair< Handshake_Type, std::vector< uint8_t > > get_next_record (bool expecting_ccs) override
bool have_more_data () const override
Protocol_Version initial_record_version () const override
std::vector< uint8_t > send (const Handshake_Message &msg) override
std::vector< uint8_t > send_under_epoch (const Handshake_Message &msg, uint16_t epoch) override
 Stream_Handshake_IO (writer_fn writer)
bool timeout_check () override

Detailed Description

Handshake IO for stream-based handshakes

Definition at line 81 of file tls_handshake_io.h.

Member Typedef Documentation

◆ writer_fn

typedef std::function<void(Record_Type, const std::vector<uint8_t>&)> Botan::TLS::Stream_Handshake_IO::writer_fn

Definition at line 83 of file tls_handshake_io.h.

Constructor & Destructor Documentation

◆ Stream_Handshake_IO()

Botan::TLS::Stream_Handshake_IO::Stream_Handshake_IO ( writer_fn writer)
inlineexplicit

Definition at line 85 of file tls_handshake_io.h.

85: m_send_hs(std::move(writer)) {}

Member Function Documentation

◆ add_record()

void Botan::TLS::Stream_Handshake_IO::add_record ( const uint8_t record[],
size_t record_len,
Record_Type type,
uint64_t sequence_number )
overridevirtual

Implements Botan::TLS::Handshake_IO.

Definition at line 43 of file tls_handshake_io.cpp.

46 {
47 if(record_type == Record_Type::Handshake) {
48 m_queue.insert(m_queue.end(), record, record + record_len);
49 } else if(record_type == Record_Type::ChangeCipherSpec) {
50 if(record_len != 1 || record[0] != 1) {
51 throw Decoding_Error("Invalid ChangeCipherSpec");
52 }
53
54 // Pretend it's a regular handshake message of zero length
55 const uint8_t ccs_hs[] = {static_cast<uint8_t>(Handshake_Type::HandshakeCCS), 0, 0, 0};
56 m_queue.insert(m_queue.end(), ccs_hs, ccs_hs + sizeof(ccs_hs));
57 } else {
58 throw Decoding_Error("Unknown message type " + std::to_string(static_cast<size_t>(record_type)) +
59 " in handshake processing");
60 }
61}

References Botan::TLS::ChangeCipherSpec, Botan::TLS::Handshake, and Botan::TLS::HandshakeCCS.

◆ format()

std::vector< uint8_t > Botan::TLS::Stream_Handshake_IO::format ( const std::vector< uint8_t > & handshake_msg,
Handshake_Type handshake_type ) const
overridevirtual

Implements Botan::TLS::Handshake_IO.

Definition at line 98 of file tls_handshake_io.cpp.

98 {
99 std::vector<uint8_t> send_buf(4 + msg.size());
100
101 const size_t buf_size = msg.size();
102
103 send_buf[0] = static_cast<uint8_t>(type);
104
105 store_be24(&send_buf[1], buf_size);
106
107 if(!msg.empty()) {
108 copy_mem(&send_buf[4], msg.data(), msg.size());
109 }
110
111 return send_buf;
112}
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144

References Botan::copy_mem().

Referenced by send().

◆ get_next_record()

std::pair< Handshake_Type, std::vector< uint8_t > > Botan::TLS::Stream_Handshake_IO::get_next_record ( bool expecting_ccs)
overridevirtual

Returns (HANDSHAKE_NONE, std::vector<>()) if no message currently available

Implements Botan::TLS::Handshake_IO.

Definition at line 63 of file tls_handshake_io.cpp.

63 {
64 if(m_queue.size() >= 4) {
65 const Handshake_Type type = static_cast<Handshake_Type>(m_queue[0]);
66
67 if(type == Handshake_Type::None) {
68 throw Decoding_Error("Invalid handshake message type");
69 }
70
71 const size_t rec_length = make_uint32(0, m_queue[1], m_queue[2], m_queue[3]);
72
73 // If we are expecting a CCS but the next queued message is not a CCS,
74 // the peer has skipped the CCS message. This can happen when the peer
75 // sends an encrypted Finished without the preceding CCS, in which case
76 // the encrypted bytes are misinterpreted as a handshake message.
77 if(expecting_ccs) {
78 const bool is_ccs = (type == Handshake_Type::HandshakeCCS && rec_length == 0);
79 if(!is_ccs) {
80 throw TLS_Exception(Alert::UnexpectedMessage, "Expected ChangeCipherSpec but got a handshake message");
81 }
82 }
83
84 const size_t length = 4 + rec_length;
85
86 if(m_queue.size() >= length) {
87 const std::vector<uint8_t> contents(m_queue.begin() + 4, m_queue.begin() + length);
88
89 m_queue.erase(m_queue.begin(), m_queue.begin() + length);
90
91 return std::make_pair(type, contents);
92 }
93 }
94
95 return std::make_pair(Handshake_Type::None, std::vector<uint8_t>());
96}
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
Definition loadstor.h:104

References Botan::TLS::HandshakeCCS, Botan::make_uint32(), and Botan::TLS::None.

◆ have_more_data()

bool Botan::TLS::Stream_Handshake_IO::have_more_data ( ) const
inlineoverridevirtual

Implements Botan::TLS::Handshake_IO.

Definition at line 91 of file tls_handshake_io.h.

91{ return !m_queue.empty(); }

◆ initial_record_version()

Protocol_Version Botan::TLS::Stream_Handshake_IO::initial_record_version ( ) const
overridevirtual

Implements Botan::TLS::Handshake_IO.

Definition at line 39 of file tls_handshake_io.cpp.

39 {
40 return Protocol_Version::TLS_V12;
41}

◆ send()

std::vector< uint8_t > Botan::TLS::Stream_Handshake_IO::send ( const Handshake_Message & msg)
overridevirtual

Implements Botan::TLS::Handshake_IO.

Definition at line 118 of file tls_handshake_io.cpp.

118 {
119 const std::vector<uint8_t> msg_bits = msg.serialize();
120
121 if(msg.type() == Handshake_Type::HandshakeCCS) {
122 m_send_hs(Record_Type::ChangeCipherSpec, msg_bits);
123 return std::vector<uint8_t>(); // not included in handshake hashes
124 }
125
126 auto buf = format(msg_bits, msg.wire_type());
127 m_send_hs(Record_Type::Handshake, buf);
128 return buf;
129}
std::vector< uint8_t > format(const std::vector< uint8_t > &handshake_msg, Handshake_Type handshake_type) const override

References Botan::TLS::ChangeCipherSpec, format(), Botan::TLS::Handshake, Botan::TLS::HandshakeCCS, Botan::TLS::Handshake_Message::serialize(), Botan::TLS::Handshake_Message::type(), and Botan::TLS::Handshake_Message::wire_type().

◆ send_under_epoch()

std::vector< uint8_t > Botan::TLS::Stream_Handshake_IO::send_under_epoch ( const Handshake_Message & msg,
uint16_t epoch )
overridevirtual

Implements Botan::TLS::Handshake_IO.

Definition at line 114 of file tls_handshake_io.cpp.

114 {
115 throw Invalid_State("Not possible to send under arbitrary epoch with stream based TLS");
116}

◆ timeout_check()

bool Botan::TLS::Stream_Handshake_IO::timeout_check ( )
inlineoverridevirtual

Implements Botan::TLS::Handshake_IO.

Definition at line 89 of file tls_handshake_io.h.

89{ return false; }

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