Botan 3.12.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 // RFC 8446 4.2.2
28 // struct {
29 // opaque cookie<1..2^16-1>;
30 // } Cookie;
31 //
32 // The wire form requires a 2-byte length field plus at least one byte of
33 // cookie data, so the minimum extension size is 3 bytes.
34 if(extension_size < 3) {
35 throw Decoding_Error("Empty cookie extension is illegal");
36 }
37
38 const uint16_t len = reader.get_uint16_t();
39
40 if(static_cast<size_t>(len) + 2 != extension_size) {
41 throw Decoding_Error("Inconsistent length in cookie extension");
42 }
43
44 m_cookie = reader.get_fixed<uint8_t>(len);
45}
46
47std::vector<uint8_t> Cookie::serialize(Connection_Side /*whoami*/) const {
48 std::vector<uint8_t> buf;
49 append_tls_length_value(buf, m_cookie, 2);
50 return buf;
51}
52
53std::vector<uint8_t> PSK_Key_Exchange_Modes::serialize(Connection_Side /*whoami*/) const {
54 std::vector<uint8_t> buf;
55
56 BOTAN_ASSERT_NOMSG(m_modes.size() < 256);
57 buf.push_back(static_cast<uint8_t>(m_modes.size()));
58 for(const auto& mode : m_modes) {
59 buf.push_back(static_cast<uint8_t>(mode));
60 }
61
62 return buf;
63}
64
66 // RFC 8446 4.2.9
67 // struct {
68 // PskKeyExchangeMode ke_modes<1..255>;
69 // } PskKeyExchangeModes;
70 //
71 // The wire form is a 1-byte length followed by mode_count mode bytes,
72 // with mode_count in [1, 255], so the extension size is in [2, 256].
73 if(extension_size < 2) {
74 throw Decoding_Error("Empty psk_key_exchange_modes extension is illegal");
75 }
76
77 const auto mode_count = reader.get_byte();
78 if(static_cast<size_t>(mode_count) + 1 != extension_size) {
79 throw Decoding_Error("Inconsistent length in psk_key_exchange_modes extension");
80 }
81
82 for(uint16_t i = 0; i < mode_count; ++i) {
83 const auto mode = static_cast<PSK_Key_Exchange_Mode>(reader.get_byte());
85 m_modes.push_back(mode);
86 }
87 }
88}
89
90std::vector<uint8_t> Certificate_Authorities::serialize(Connection_Side /*whoami*/) const {
91 std::vector<uint8_t> out;
92 std::vector<uint8_t> dn_list;
93
94 for(const auto& dn : m_distinguished_names) {
95 std::vector<uint8_t> encoded_dn;
96 auto encoder = DER_Encoder(encoded_dn);
97 dn.encode_into(encoder);
98 append_tls_length_value(dn_list, encoded_dn, 2);
99 }
100
101 append_tls_length_value(out, dn_list, 2);
102
103 return out;
104}
105
107 if(extension_size < 2) {
108 throw Decoding_Error("Empty certificate_authorities extension is illegal");
109 }
110
111 const uint16_t purported_size = reader.get_uint16_t();
112
113 if(reader.remaining_bytes() != purported_size) {
114 throw Decoding_Error("Inconsistent length in certificate_authorities extension");
115 }
116
117 // RFC 8446 4.2.4: DistinguishedName authorities<3..2^16-1>;
118 if(purported_size < 3) {
119 throw Decoding_Error("Empty certificate_authorities list is illegal");
120 }
121
122 while(reader.has_remaining()) {
123 // RFC 8446 4.2.4: opaque DistinguishedName<1..2^16-1>
124 const std::vector<uint8_t> name_bits = reader.get_range<uint8_t>(2, 1, 65535);
125
126 BER_Decoder decoder(name_bits, BER_Decoder::Limits::DER());
127 m_distinguished_names.emplace_back();
128 decoder.decode(m_distinguished_names.back()).verify_end();
129 }
130}
131
132Certificate_Authorities::Certificate_Authorities(std::vector<X509_DN> acceptable_DNs) :
133 m_distinguished_names(std::move(acceptable_DNs)) {}
134
135std::vector<uint8_t> EarlyDataIndication::serialize(Connection_Side /*whoami*/) const {
136 std::vector<uint8_t> result;
137 if(m_max_early_data_size.has_value()) {
138 const auto max_data = m_max_early_data_size.value();
139 result.push_back(get_byte<0>(max_data));
140 result.push_back(get_byte<1>(max_data));
141 result.push_back(get_byte<2>(max_data));
142 result.push_back(get_byte<3>(max_data));
143 }
144 return result;
145}
146
148 uint16_t extension_size,
149 Handshake_Type message_type) {
150 if(message_type == Handshake_Type::NewSessionTicket) {
151 if(extension_size != 4) {
152 throw TLS_Exception(Alert::DecodeError,
153 "Received an early_data extension in a NewSessionTicket message "
154 "without maximum early data size indication");
155 }
156
157 m_max_early_data_size = reader.get_uint32_t();
158 } else if(extension_size != 0) {
159 throw TLS_Exception(Alert::DecodeError,
160 "Received an early_data extension containing an unexpected data "
161 "size indication");
162 }
163}
164
166 // This extension may be empty by definition but still carry information
167 return false;
168}
169
170} // namespace Botan::TLS
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
static Limits DER()
Definition ber_dec.h:35
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
std::vector< T > get_range(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition tls_reader.h:110
size_t remaining_bytes() const
Definition tls_reader.h:37
std::vector< T > get_fixed(size_t size)
Definition tls_reader.h:129
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