Botan 3.11.0
Crypto and TLS for C&
msg_server_hello.cpp
Go to the documentation of this file.
1/*
2* TLS Server Hello and Server Hello Done
3* (C) 2004-2011,2015,2016,2019 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/tls_alert.h>
17#include <botan/tls_exceptn.h>
18#include <botan/tls_policy.h>
19#include <botan/internal/ct_utils.h>
20#include <botan/internal/tls_reader.h>
21
22namespace Botan::TLS {
23
25 Protocol_Version offered_version,
26 Callbacks& cb,
27 const Policy& policy) {
28 BOTAN_UNUSED(offered_version);
29 auto random = make_hello_random(rng, cb, policy);
30
31 // RFC 8446 4.1.3
32 // TLS 1.3 has a downgrade protection mechanism embedded in the server's
33 // random value. TLS 1.3 servers which negotiate TLS 1.2 or below in
34 // response to a ClientHello MUST set the last 8 bytes of their Random
35 // value specially in their ServerHello.
36 //
37 // If negotiating TLS 1.2, TLS 1.3 servers MUST set the last 8 bytes of
38 // their Random value to the bytes: [DOWNGRADE_TLS12]
39 if(offered_version.is_pre_tls_13() && policy.allow_tls13()) {
40 constexpr size_t downgrade_signal_length = sizeof(DOWNGRADE_TLS12);
41 BOTAN_ASSERT_NOMSG(random.size() >= downgrade_signal_length);
42 const auto lastbytes = std::span{random}.last(downgrade_signal_length);
43 store_be(DOWNGRADE_TLS12, lastbytes);
44 }
45
46 return random;
47}
48
49Server_Hello_Internal::Server_Hello_Internal(const std::vector<uint8_t>& buf) {
50 if(buf.size() < 38) {
51 throw Decoding_Error("Server_Hello: Packet corrupted");
52 }
53
54 TLS_Data_Reader reader("ServerHello", buf);
55
56 const uint8_t major_version = reader.get_byte();
57 const uint8_t minor_version = reader.get_byte();
58
59 m_legacy_version = Protocol_Version(major_version, minor_version);
60
61 // RFC 8446 4.1.3
62 // Upon receiving a message with type server_hello, implementations MUST
63 // first examine the Random value and, if it matches this value, process
64 // it as described in Section 4.1.4 [Hello Retry Request]).
65 m_random = reader.get_fixed<uint8_t>(32);
66 m_is_hello_retry_request = CT::is_equal<uint8_t>(m_random, HELLO_RETRY_REQUEST_MARKER).as_bool();
67
68 m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32));
69 m_ciphersuite = reader.get_uint16_t();
70 m_comp_method = reader.get_byte();
71
72 // Note that this code path might parse a TLS 1.2 (or older) server hello message that
73 // is nevertheless marked as being a 'hello retry request' (potentially maliciously).
74 // Extension parsing will however not be affected by the associated flag.
75 // Only after parsing the extensions will the upstream code be able to decide
76 // whether we're dealing with TLS 1.3 or older.
77 m_extensions.deserialize(reader,
80}
81
83 // RFC 8446 4.2.1
84 // A server which negotiates a version of TLS prior to TLS 1.3 MUST set
85 // ServerHello.version and MUST NOT send the "supported_versions"
86 // extension. A server which negotiates TLS 1.3 MUST respond by sending
87 // a "supported_versions" extension containing the selected version
88 // value (0x0304).
89 //
90 // Note: Here we just take a message parsing decision, further validation of
91 // the extension's contents is done later.
92 return (extensions().has<Supported_Versions>()) ? Protocol_Version::TLS_V13 : m_legacy_version;
93}
94
95Server_Hello::Server_Hello(std::unique_ptr<Server_Hello_Internal> data) : m_data(std::move(data)) {}
96
97Server_Hello::Server_Hello(Server_Hello&&) noexcept = default;
98Server_Hello& Server_Hello::operator=(Server_Hello&&) noexcept = default;
99
100Server_Hello::~Server_Hello() = default;
101
102/*
103* Serialize a Server Hello message
104*/
105std::vector<uint8_t> Server_Hello::serialize() const {
106 std::vector<uint8_t> buf;
107 buf.reserve(1024); // working around GCC warning
108
109 buf.push_back(m_data->legacy_version().major_version());
110 buf.push_back(m_data->legacy_version().minor_version());
111 buf += m_data->random();
112
113 append_tls_length_value(buf, m_data->session_id().get(), 1);
114
115 buf.push_back(get_byte<0>(m_data->ciphersuite()));
116 buf.push_back(get_byte<1>(m_data->ciphersuite()));
117
118 buf.push_back(m_data->comp_method());
119
120 buf += m_data->extensions().serialize(Connection_Side::Server);
121
122 return buf;
123}
124
128
130 return m_data->legacy_version();
131}
132
133const std::vector<uint8_t>& Server_Hello::random() const {
134 return m_data->random();
135}
136
138 return m_data->comp_method();
139}
140
142 return m_data->session_id();
143}
144
146 return m_data->ciphersuite();
147}
148
149std::set<Extension_Code> Server_Hello::extension_types() const {
150 return m_data->extensions().extension_types();
151}
152
154 return m_data->extensions();
155}
156
157Server_Hello_12_Shim::Server_Hello_12_Shim(const std::vector<uint8_t>& buf) :
158 Server_Hello_12_Shim(std::make_unique<Server_Hello_Internal>(buf)) {}
159
160Server_Hello_12_Shim::Server_Hello_12_Shim(std::unique_ptr<Server_Hello_Internal> data) :
161 Server_Hello(std::move(data)) {
162 if(!m_data->version().is_pre_tls_13()) {
163 throw TLS_Exception(Alert::ProtocolVersion, "Expected server hello of (D)TLS 1.2 or lower");
164 }
165}
166
170
171std::optional<Protocol_Version> Server_Hello_12_Shim::random_signals_downgrade() const {
172 const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
173 if(last8 == DOWNGRADE_TLS11) {
174 return Protocol_Version::TLS_V11;
175 }
176 if(last8 == DOWNGRADE_TLS12) {
177 return Protocol_Version::TLS_V12;
178 }
179
180 return std::nullopt;
181}
182
183} // namespace Botan::TLS
#define BOTAN_UNUSED
Definition assert.h:144
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
virtual bool allow_tls13() const
Server_Hello_12_Shim(const std::vector< uint8_t > &buf)
Protocol_Version selected_version() const final
std::optional< Protocol_Version > random_signals_downgrade() const
Server_Hello_Internal(const std::vector< uint8_t > &buf)
const Extensions & extensions() const
Server_Hello(const Server_Hello &)=delete
std::vector< uint8_t > serialize() const override
std::set< Extension_Code > extension_types() const
Handshake_Type type() const override
const Session_ID & session_id() const
const std::vector< uint8_t > & random() const
std::unique_ptr< Server_Hello_Internal > m_data
const Extensions & extensions() const
Protocol_Version legacy_version() const
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
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
Definition ct_utils.h:798
constexpr uint64_t DOWNGRADE_TLS12
Definition tls_magic.h:118
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
std::vector< uint8_t > make_server_hello_random(RandomNumberGenerator &rng, Protocol_Version offered_version, Callbacks &cb, const Policy &policy)
constexpr uint64_t DOWNGRADE_TLS11
Definition tls_magic.h:107
constexpr std::array< uint8_t, 32 > HELLO_RETRY_REQUEST_MARKER
Definition tls_magic.h:126
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:745
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504