Botan 3.11.0
Crypto and TLS for C&
msg_client_hello.cpp
Go to the documentation of this file.
1/*
2* TLS Client Hello Messages
3* (C) 2004-2011,2015,2016 Jack Lloyd
4* 2016 Matthias Gierlings
5* 2017 Harry Reimann, Rohde & Schwarz Cybersecurity
6* 2021 Elektrobit Automotive GmbH
7* 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
8* 2026 René Meusel - Rohde & Schwarz Cybersecurity GmbH
9*
10* Botan is released under the Simplified BSD License (see license.txt)
11*/
12
13#include <botan/tls_messages.h>
14#include <botan/internal/tls_messages_internal.h>
15
16#include <botan/hash.h>
17#include <botan/rng.h>
18#include <botan/tls_callbacks.h>
19#include <botan/tls_policy.h>
20#include <botan/internal/tls_reader.h>
21#include <algorithm>
22
23namespace Botan::TLS {
24
25std::vector<uint8_t> make_hello_random(RandomNumberGenerator& rng, Callbacks& cb, const Policy& policy) {
26 auto buf = rng.random_vec<std::vector<uint8_t>>(32);
27
28 if(policy.hash_hello_random()) {
29 auto sha256 = HashFunction::create_or_throw("SHA-256");
30 sha256->update(buf);
31 sha256->final(buf);
32 }
33
34 // TLS 1.3 does not require the insertion of a timestamp in the client hello
35 // random. When offering both TLS 1.2 and 1.3 we nevertheless comply with the
36 // legacy specification.
37 if(policy.include_time_in_hello_random() && (policy.allow_tls12() || policy.allow_dtls12())) {
38 const uint32_t time32 = static_cast<uint32_t>(std::chrono::system_clock::to_time_t(cb.tls_current_timestamp()));
39
40 store_be(time32, buf.data());
41 }
42
43 return buf;
44}
45
46Client_Hello_Internal::Client_Hello_Internal(const std::vector<uint8_t>& buf) {
47 if(buf.size() < 41) {
48 throw Decoding_Error("Client_Hello: Packet corrupted");
49 }
50
51 TLS_Data_Reader reader("ClientHello", buf);
52
53 const uint8_t major_version = reader.get_byte();
54 const uint8_t minor_version = reader.get_byte();
55
56 m_legacy_version = Protocol_Version(major_version, minor_version);
57 m_random = reader.get_fixed<uint8_t>(32);
58 m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32));
59
60 if(m_legacy_version.is_datagram_protocol()) {
61 auto sha256 = HashFunction::create_or_throw("SHA-256");
62 sha256->update(reader.get_data_read_so_far());
63
64 m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
65
66 sha256->update(reader.get_remaining());
67 m_cookie_input_bits = sha256->final_stdvec();
68 }
69
70 m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
71 m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
72
74}
75
77 // RFC 8446 4.2.1
78 // If [the "supported_versions"] extension is not present, servers
79 // which are compliant with this specification and which also support
80 // TLS 1.2 MUST negotiate TLS 1.2 or prior as specified in [RFC5246],
81 // even if ClientHello.legacy_version is 0x0304 or later.
82 //
83 // RFC 8446 4.2.1
84 // Servers MUST be prepared to receive ClientHellos that include
85 // [the supported_versions] extension but do not include 0x0304 in
86 // the list of versions.
87 //
88 // RFC 8446 4.1.2
89 // TLS 1.3 ClientHellos are identified as having a legacy_version of
90 // 0x0303 and a supported_versions extension present with 0x0304 as
91 // the highest version indicated therein.
92 if(!extensions().has<Supported_Versions>() ||
93 !extensions().get<Supported_Versions>()->supports(Protocol_Version::TLS_V13)) {
94 // The exact legacy_version is ignored we just inspect it to
95 // distinguish TLS and DTLS.
96 return (m_legacy_version.is_datagram_protocol()) ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
97 }
98
99 // Note: The Client_Hello_13 class will make sure that legacy_version
100 // is exactly 0x0303 (aka ossified TLS 1.2)
101 return Protocol_Version::TLS_V13;
102}
104Client_Hello::Client_Hello(Client_Hello&&) noexcept = default;
105Client_Hello& Client_Hello::operator=(Client_Hello&&) noexcept = default;
106
107Client_Hello::~Client_Hello() = default;
108
110
111/*
112* Read a counterparty client hello
113*/
114Client_Hello::Client_Hello(std::unique_ptr<Client_Hello_Internal> data) : m_data(std::move(data)) {
116}
117
121
123 return m_data->legacy_version();
124}
125
126const std::vector<uint8_t>& Client_Hello::random() const {
127 return m_data->random();
128}
129
131 return m_data->session_id();
132}
133
134const std::vector<uint8_t>& Client_Hello::compression_methods() const {
135 return m_data->comp_methods();
136}
137
138const std::vector<uint16_t>& Client_Hello::ciphersuites() const {
139 return m_data->ciphersuites();
140}
141
142std::set<Extension_Code> Client_Hello::extension_types() const {
143 return m_data->extensions().extension_types();
144}
147 return m_data->extensions();
148}
149
150/*
151* Serialize a Client Hello message
152*/
153std::vector<uint8_t> Client_Hello::serialize() const {
154 std::vector<uint8_t> buf;
155 buf.reserve(1024); // working around GCC warning
156
157 buf.push_back(m_data->legacy_version().major_version());
158 buf.push_back(m_data->legacy_version().minor_version());
159 buf += m_data->random();
160
161 append_tls_length_value(buf, m_data->session_id().get(), 1);
162
163 if(m_data->legacy_version().is_datagram_protocol()) {
164 append_tls_length_value(buf, m_data->hello_cookie(), 1);
165 }
166
167 append_tls_length_value(buf, m_data->ciphersuites(), 2);
168 append_tls_length_value(buf, m_data->comp_methods(), 1);
169
170 /*
171 * May not want to send extensions at all in some cases. If so,
172 * should include SCSV value (if reneg info is empty, if not we are
173 * renegotiating with a modern server)
174 */
175
176 buf += m_data->extensions().serialize(Connection_Side::Client);
177
178 return buf;
179}
180
181std::vector<uint8_t> Client_Hello::cookie_input_data() const {
182 BOTAN_STATE_CHECK(!m_data->hello_cookie_input_bits().empty());
183
184 return m_data->hello_cookie_input_bits();
185}
186
187/*
188* Check if we offered this ciphersuite
189*/
190bool Client_Hello::offered_suite(uint16_t ciphersuite) const {
191 return std::find(m_data->ciphersuites().cbegin(), m_data->ciphersuites().cend(), ciphersuite) !=
192 m_data->ciphersuites().cend();
193}
194
195std::vector<Signature_Scheme> Client_Hello::signature_schemes() const {
196 if(const Signature_Algorithms* sigs = m_data->extensions().get<Signature_Algorithms>()) {
197 return sigs->supported_schemes();
198 }
199 return {};
200}
201
202std::vector<Signature_Scheme> Client_Hello::certificate_signature_schemes() const {
203 // RFC 8446 4.2.3
204 // If no "signature_algorithms_cert" extension is present, then the
205 // "signature_algorithms" extension also applies to signatures appearing
206 // in certificates.
207 if(const Signature_Algorithms_Cert* sigs = m_data->extensions().get<Signature_Algorithms_Cert>()) {
208 return sigs->supported_schemes();
209 } else {
210 return signature_schemes();
211 }
212}
213
214std::vector<Group_Params> Client_Hello::supported_ecc_curves() const {
215 if(const Supported_Groups* groups = m_data->extensions().get<Supported_Groups>()) {
216 return groups->ec_groups();
217 }
218 return {};
219}
220
221std::vector<Group_Params> Client_Hello::supported_dh_groups() const {
222 if(const Supported_Groups* groups = m_data->extensions().get<Supported_Groups>()) {
223 return groups->dh_groups();
224 }
225 return std::vector<Group_Params>();
226}
227
228std::string Client_Hello::sni_hostname() const {
229 if(const Server_Name_Indicator* sni = m_data->extensions().get<Server_Name_Indicator>()) {
230 return sni->host_name();
231 }
232 return "";
233}
234
235std::vector<Protocol_Version> Client_Hello::supported_versions() const {
236 if(const Supported_Versions* versions = m_data->extensions().get<Supported_Versions>()) {
237 return versions->versions();
238 }
239 return {};
240}
241
243 return m_data->extensions().has<Application_Layer_Protocol_Notification>();
244}
245
247 return m_data->extensions().has<Signature_Algorithms>();
248}
249
250std::vector<std::string> Client_Hello::next_protocols() const {
251 if(auto* alpn = m_data->extensions().get<Application_Layer_Protocol_Notification>()) {
252 return alpn->protocols();
253 }
254 return {};
255}
256
257std::vector<uint16_t> Client_Hello::srtp_profiles() const {
258 if(const SRTP_Protection_Profiles* srtp = m_data->extensions().get<SRTP_Protection_Profiles>()) {
259 return srtp->profiles();
260 }
261 return {};
262}
263
264const std::vector<uint8_t>& Client_Hello::cookie() const {
265 return m_data->hello_cookie();
266}
267
268Client_Hello_12_Shim::Client_Hello_12_Shim(std::unique_ptr<Client_Hello_Internal> data) :
269 Client_Hello(std::move(data)) {}
270
271Client_Hello_12_Shim::Client_Hello_12_Shim(const std::vector<uint8_t>& buf) :
272 Client_Hello_12_Shim(std::make_unique<Client_Hello_Internal>(buf)) {}
273
274} // namespace Botan::TLS
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:308
void random_vec(std::span< uint8_t > v)
Definition rng.h:204
virtual std::chrono::system_clock::time_point tls_current_timestamp()
Client_Hello_12_Shim(const std::vector< uint8_t > &buf)
Client_Hello(const Client_Hello &)=delete
const Extensions & extensions() const
const std::vector< uint8_t > & cookie() const
std::string sni_hostname() const
std::vector< uint8_t > serialize() const override
const std::vector< uint8_t > & random() const
std::vector< Signature_Scheme > signature_schemes() const
const Extensions & extensions() const
bool offered_suite(uint16_t ciphersuite) const
std::unique_ptr< Client_Hello_Internal > m_data
std::vector< Group_Params > supported_ecc_curves() const
std::vector< Signature_Scheme > certificate_signature_schemes() const
const std::vector< uint16_t > & ciphersuites() const
std::vector< uint8_t > cookie_input_data() const
std::set< Extension_Code > extension_types() const
std::vector< Group_Params > supported_dh_groups() const
std::vector< std::string > next_protocols() const
const Session_ID & session_id() const
Protocol_Version legacy_version() const
const std::vector< uint8_t > & compression_methods() const
std::vector< uint16_t > srtp_profiles() const
Handshake_Type type() const override
std::vector< Protocol_Version > supported_versions() const
Client_Hello(const Client_Hello &)=delete
virtual bool include_time_in_hello_random() const
virtual bool allow_tls12() const
virtual bool hash_hello_random() const
virtual bool allow_dtls12() const
std::vector< uint8_t > get_remaining()
Definition tls_reader.h:41
std::vector< T > get_range(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition tls_reader.h:110
std::vector< T > get_fixed(size_t size)
Definition tls_reader.h:129
std::vector< uint8_t > get_data_read_so_far()
Definition tls_reader.h:46
std::vector< T > get_range_vector(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition tls_reader.h:117
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
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, Callbacks &cb, const Policy &policy)
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:745