Botan 3.11.0
Crypto and TLS for C&
tls_extensions_13.cpp
Go to the documentation of this file.
1/*
2* TLS 1.3 Specific Extensions
3* (C) 2011,2012,2015,2016 Jack Lloyd
4* 2016 Juraj Somorovsky
5* 2021 Elektrobit Automotive GmbH
6* 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
7* 2023 Mateusz Berezecki
8* 2023 Fabian Albert, René Meusel - Rohde & Schwarz Cybersecurity
9* 2026 René Meusel - Rohde & Schwarz Cybersecurity
10*
11* Botan is released under the Simplified BSD License (see license.txt)
12*/
13
14#include <botan/tls_extensions_13.h>
15
16#include <botan/ber_dec.h>
17#include <botan/der_enc.h>
18#include <botan/tls_alert.h>
19#include <botan/tls_exceptn.h>
20#include <botan/internal/tls_reader.h>
21
22namespace Botan::TLS {
23
24Cookie::Cookie(const std::vector<uint8_t>& cookie) : m_cookie(cookie) {}
25
26Cookie::Cookie(TLS_Data_Reader& reader, uint16_t extension_size) {
27 if(extension_size == 0) {
28 return;
29 }
30
31 const uint16_t len = reader.get_uint16_t();
32
33 if(len == 0) {
34 // Based on RFC 8446 4.2.2, len of the Cookie buffer must be at least 1
35 throw Decoding_Error("Cookie length must be at least 1 byte");
36 }
37
38 if(len > reader.remaining_bytes()) {
39 throw Decoding_Error("Not enough bytes in the buffer to decode Cookie");
40 }
41
42 for(size_t i = 0; i < len; ++i) {
43 m_cookie.push_back(reader.get_byte());
44 }
45}
46
47std::vector<uint8_t> Cookie::serialize(Connection_Side /*whoami*/) const {
48 std::vector<uint8_t> buf;
49
50 const uint16_t len = static_cast<uint16_t>(m_cookie.size());
51
52 buf.push_back(get_byte<0>(len));
53 buf.push_back(get_byte<1>(len));
54
55 for(const auto& cookie_byte : m_cookie) {
56 buf.push_back(cookie_byte);
57 }
58
59 return buf;
60}
61
62std::vector<uint8_t> PSK_Key_Exchange_Modes::serialize(Connection_Side /*whoami*/) const {
63 std::vector<uint8_t> buf;
64
65 BOTAN_ASSERT_NOMSG(m_modes.size() < 256);
66 buf.push_back(static_cast<uint8_t>(m_modes.size()));
67 for(const auto& mode : m_modes) {
68 buf.push_back(static_cast<uint8_t>(mode));
69 }
70
71 return buf;
72}
73
75 if(extension_size < 2) {
76 throw Decoding_Error("Empty psk_key_exchange_modes extension is illegal");
77 }
78
79 const auto mode_count = reader.get_byte();
80 for(uint16_t i = 0; i < mode_count; ++i) {
81 const auto mode = static_cast<PSK_Key_Exchange_Mode>(reader.get_byte());
83 m_modes.push_back(mode);
84 }
85 }
86}
87
88std::vector<uint8_t> Certificate_Authorities::serialize(Connection_Side /*whoami*/) const {
89 std::vector<uint8_t> out;
90 std::vector<uint8_t> dn_list;
91
92 for(const auto& dn : m_distinguished_names) {
93 std::vector<uint8_t> encoded_dn;
94 auto encoder = DER_Encoder(encoded_dn);
95 dn.encode_into(encoder);
96 append_tls_length_value(dn_list, encoded_dn, 2);
97 }
98
99 append_tls_length_value(out, dn_list, 2);
100
101 return out;
102}
103
105 if(extension_size < 2) {
106 throw Decoding_Error("Empty certificate_authorities extension is illegal");
107 }
108
109 const uint16_t purported_size = reader.get_uint16_t();
110
111 if(reader.remaining_bytes() != purported_size) {
112 throw Decoding_Error("Inconsistent length in certificate_authorities extension");
113 }
114
115 while(reader.has_remaining()) {
116 std::vector<uint8_t> name_bits = reader.get_tls_length_value(2);
117
118 BER_Decoder decoder(name_bits.data(), name_bits.size());
119 m_distinguished_names.emplace_back();
120 decoder.decode(m_distinguished_names.back());
121 }
122}
123
124Certificate_Authorities::Certificate_Authorities(std::vector<X509_DN> acceptable_DNs) :
125 m_distinguished_names(std::move(acceptable_DNs)) {}
126
127std::vector<uint8_t> EarlyDataIndication::serialize(Connection_Side /*whoami*/) const {
128 std::vector<uint8_t> result;
129 if(m_max_early_data_size.has_value()) {
130 const auto max_data = m_max_early_data_size.value();
131 result.push_back(get_byte<0>(max_data));
132 result.push_back(get_byte<1>(max_data));
133 result.push_back(get_byte<2>(max_data));
134 result.push_back(get_byte<3>(max_data));
135 }
136 return result;
137}
138
140 uint16_t extension_size,
141 Handshake_Type message_type) {
142 if(message_type == Handshake_Type::NewSessionTicket) {
143 if(extension_size != 4) {
144 throw TLS_Exception(Alert::DecodeError,
145 "Received an early_data extension in a NewSessionTicket message "
146 "without maximum early data size indication");
147 }
148
149 m_max_early_data_size = reader.get_uint32_t();
150 } else if(extension_size != 0) {
151 throw TLS_Exception(Alert::DecodeError,
152 "Received an early_data extension containing an unexpected data "
153 "size indication");
154 }
155}
156
158 // This extension may be empty by definition but still carry information
159 return false;
160}
161
162} // namespace Botan::TLS
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
BER_Decoder & decode(bool &out)
Definition ber_dec.h:188
std::vector< uint8_t > serialize(Connection_Side whoami) const override
Certificate_Authorities(TLS_Data_Reader &reader, uint16_t extension_size)
Cookie(const std::vector< uint8_t > &cookie)
std::vector< uint8_t > serialize(Connection_Side whoami) const override
std::vector< uint8_t > serialize(Connection_Side whoami) const override
EarlyDataIndication(TLS_Data_Reader &reader, uint16_t extension_size, Handshake_Type message_type)
PSK_Key_Exchange_Modes(std::vector< PSK_Key_Exchange_Mode > modes)
std::vector< uint8_t > serialize(Connection_Side whoami) const override
size_t remaining_bytes() const
Definition tls_reader.h:37
std::vector< uint8_t > get_tls_length_value(size_t len_bytes)
Definition tls_reader.h:105
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
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79