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