• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 21863608093

10 Feb 2026 11:46AM UTC coverage: 90.064% (-0.004%) from 90.068%
21863608093

Pull #5303

github

web-flow
Merge aea1c629d into 1d119e57a
Pull Request #5303: Refactor: Organize TLS Extensions into TLS 1.2 and 1.3 Modules

102231 of 113509 relevant lines covered (90.06%)

11483899.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.11
/src/lib/tls/msg_server_hello.cpp
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

22
namespace Botan::TLS {
23

24
std::vector<uint8_t> make_server_hello_random(RandomNumberGenerator& rng,
1,123✔
25
                                              Protocol_Version offered_version,
26
                                              Callbacks& cb,
27
                                              const Policy& policy) {
28
   BOTAN_UNUSED(offered_version);
1,123✔
29
   auto random = make_hello_random(rng, cb, policy);
1,123✔
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()) {
1,123✔
40
      constexpr size_t downgrade_signal_length = sizeof(DOWNGRADE_TLS12);
484✔
41
      BOTAN_ASSERT_NOMSG(random.size() >= downgrade_signal_length);
484✔
42
      const auto lastbytes = std::span{random}.last(downgrade_signal_length);
484✔
43
      store_be(DOWNGRADE_TLS12, lastbytes);
968✔
44
   }
45

46
   return random;
1,123✔
47
}
×
48

49
Server_Hello_Internal::Server_Hello_Internal(const std::vector<uint8_t>& buf) {
3,569✔
50
   if(buf.size() < 38) {
3,569✔
51
      throw Decoding_Error("Server_Hello: Packet corrupted");
6✔
52
   }
53

54
   TLS_Data_Reader reader("ServerHello", buf);
3,563✔
55

56
   const uint8_t major_version = reader.get_byte();
3,563✔
57
   const uint8_t minor_version = reader.get_byte();
3,563✔
58

59
   m_legacy_version = Protocol_Version(major_version, minor_version);
3,563✔
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);
3,563✔
66
   m_is_hello_retry_request = CT::is_equal<uint8_t>(m_random, HELLO_RETRY_REQUEST_MARKER).as_bool();
7,126✔
67

68
   m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32));
3,563✔
69
   m_ciphersuite = reader.get_uint16_t();
3,554✔
70
   m_comp_method = reader.get_byte();
3,552✔
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,
3,551✔
78
                            Connection_Side::Server,
79
                            m_is_hello_retry_request ? Handshake_Type::HelloRetryRequest : Handshake_Type::ServerHello);
3,551✔
80
}
3,873✔
81

82
Protocol_Version Server_Hello_Internal::version() const {
5,417✔
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;
5,417✔
93
}
94

95
Server_Hello::Server_Hello(std::unique_ptr<Server_Hello_Internal> data) : m_data(std::move(data)) {}
4,814✔
96

97
Server_Hello::Server_Hello(Server_Hello&&) noexcept = default;
11,596✔
98
Server_Hello& Server_Hello::operator=(Server_Hello&&) noexcept = default;
1✔
99

100
Server_Hello::~Server_Hello() = default;
16,397✔
101

102
/*
103
* Serialize a Server Hello message
104
*/
105
std::vector<uint8_t> Server_Hello::serialize() const {
1,397✔
106
   std::vector<uint8_t> buf;
1,397✔
107
   buf.reserve(1024);  // working around GCC warning
1,397✔
108

109
   buf.push_back(m_data->legacy_version().major_version());
1,397✔
110
   buf.push_back(m_data->legacy_version().minor_version());
1,397✔
111
   buf += m_data->random();
1,397✔
112

113
   append_tls_length_value(buf, m_data->session_id().get(), 1);
1,397✔
114

115
   buf.push_back(get_byte<0>(m_data->ciphersuite()));
1,397✔
116
   buf.push_back(get_byte<1>(m_data->ciphersuite()));
1,397✔
117

118
   buf.push_back(m_data->comp_method());
1,397✔
119

120
   buf += m_data->extensions().serialize(Connection_Side::Server);
1,397✔
121

122
   return buf;
1,397✔
123
}
×
124

125
Handshake_Type Server_Hello::type() const {
7,382✔
126
   return Handshake_Type::ServerHello;
7,382✔
127
}
128

129
Protocol_Version Server_Hello::legacy_version() const {
13,969✔
130
   return m_data->legacy_version();
13,969✔
131
}
132

133
const std::vector<uint8_t>& Server_Hello::random() const {
3,834✔
134
   return m_data->random();
3,834✔
135
}
136

137
uint8_t Server_Hello::compression_method() const {
6,512✔
138
   return m_data->comp_method();
6,512✔
139
}
140

141
const Session_ID& Server_Hello::session_id() const {
6,918✔
142
   return m_data->session_id();
6,918✔
143
}
144

145
uint16_t Server_Hello::ciphersuite() const {
14,948✔
146
   return m_data->ciphersuite();
14,948✔
147
}
148

149
std::set<Extension_Code> Server_Hello::extension_types() const {
2,319✔
150
   return m_data->extensions().extension_types();
2,319✔
151
}
152

153
const Extensions& Server_Hello::extensions() const {
8,177✔
154
   return m_data->extensions();
8,177✔
155
}
156

157
Server_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

160
Server_Hello_12_Shim::Server_Hello_12_Shim(std::unique_ptr<Server_Hello_Internal> data) :
3,844✔
161
      Server_Hello(std::move(data)) {
3,844✔
162
   if(!m_data->version().is_pre_tls_13()) {
7,688✔
163
      throw TLS_Exception(Alert::ProtocolVersion, "Expected server hello of (D)TLS 1.2 or lower");
×
164
   }
165
}
3,844✔
166

167
Protocol_Version Server_Hello_12_Shim::selected_version() const {
492✔
168
   return legacy_version();
492✔
169
}
170

171
std::optional<Protocol_Version> Server_Hello_12_Shim::random_signals_downgrade() const {
613✔
172
   const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
613✔
173
   if(last8 == DOWNGRADE_TLS11) {
613✔
174
      return Protocol_Version::TLS_V11;
×
175
   }
176
   if(last8 == DOWNGRADE_TLS12) {
613✔
177
      return Protocol_Version::TLS_V12;
1✔
178
   }
179

180
   return std::nullopt;
612✔
181
}
182

183
}  // namespace Botan::TLS
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc