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

randombit / botan / 25139258422

29 Apr 2026 08:02PM UTC coverage: 89.37% (-0.02%) from 89.385%
25139258422

push

github

web-flow
Merge pull request #5550 from randombit/jack/tls-misc

TLS conformance, hardening, and performance fixes

107055 of 119789 relevant lines covered (89.37%)

11415549.66 hits per line

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

92.0
/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,459✔
25
                                              Protocol_Version offered_version,
26
                                              Callbacks& cb,
27
                                              const Policy& policy) {
28
   auto random = make_hello_random(rng, cb, policy);
1,459✔
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()) {
1,459✔
39
      constexpr size_t downgrade_signal_length = sizeof(DOWNGRADE_TLS12);
609✔
40
      BOTAN_ASSERT_NOMSG(random.size() >= downgrade_signal_length);
609✔
41
      const auto lastbytes = std::span{random}.last(downgrade_signal_length);
609✔
42
      store_be(DOWNGRADE_TLS12, lastbytes);
1,218✔
43
   }
44

45
   return random;
1,459✔
46
}
×
47

48
Server_Hello_Internal::Server_Hello_Internal(const std::vector<uint8_t>& buf) {
4,241✔
49
   if(buf.size() < 38) {
4,241✔
50
      throw Decoding_Error("Server_Hello: Packet corrupted");
10✔
51
   }
52

53
   TLS_Data_Reader reader("ServerHello", buf);
4,231✔
54

55
   const uint8_t major_version = reader.get_byte();
4,231✔
56
   const uint8_t minor_version = reader.get_byte();
4,231✔
57

58
   m_legacy_version = Protocol_Version(major_version, minor_version);
4,231✔
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);
4,231✔
65
   m_is_hello_retry_request = CT::is_equal<uint8_t>(m_random, HELLO_RETRY_REQUEST_MARKER).as_bool();
8,462✔
66

67
   m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32));
4,231✔
68
   m_ciphersuite = reader.get_uint16_t();
4,217✔
69
   m_comp_method = reader.get_byte();
4,215✔
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,
4,214✔
77
                            Connection_Side::Server,
78
                            m_is_hello_retry_request ? Handshake_Type::HelloRetryRequest : Handshake_Type::ServerHello);
4,214✔
79
}
4,617✔
80

81
Protocol_Version Server_Hello_Internal::version() const {
6,181✔
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;
6,181✔
92
}
93

94
Server_Hello::Server_Hello(std::unique_ptr<Server_Hello_Internal> data) : m_data(std::move(data)) {}
5,565✔
95

96
Server_Hello::Server_Hello(Server_Hello&&) noexcept = default;
12,332✔
97
Server_Hello& Server_Hello::operator=(Server_Hello&&) noexcept = default;
1✔
98

99
Server_Hello::~Server_Hello() = default;
17,884✔
100

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

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

112
   append_tls_length_value(buf, m_data->session_id().get(), 1);
1,507✔
113

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

117
   buf.push_back(m_data->comp_method());
1,507✔
118

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

121
   return buf;
1,507✔
122
}
×
123

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

128
Protocol_Version Server_Hello::legacy_version() const {
16,861✔
129
   return m_data->legacy_version();
16,861✔
130
}
131

132
const std::vector<uint8_t>& Server_Hello::random() const {
4,033✔
133
   return m_data->random();
4,033✔
134
}
135

136
uint8_t Server_Hello::compression_method() const {
7,387✔
137
   return m_data->comp_method();
7,387✔
138
}
139

140
const Session_ID& Server_Hello::session_id() const {
7,625✔
141
   return m_data->session_id();
7,625✔
142
}
143

144
uint16_t Server_Hello::ciphersuite() const {
17,980✔
145
   return m_data->ciphersuite();
17,980✔
146
}
147

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

152
const Extensions& Server_Hello::extensions() const {
12,231✔
153
   return m_data->extensions();
12,231✔
154
}
155

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

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

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

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

179
   return std::nullopt;
643✔
180
}
181

182
}  // 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