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

randombit / botan / 21755977799

06 Feb 2026 03:28PM UTC coverage: 91.63% (+1.6%) from 90.073%
21755977799

Pull #5292

github

web-flow
Merge d523f1361 into 8ea0ca252
Pull Request #5292: Refactor: Disentangle Server_Hello implementations

104016 of 113517 relevant lines covered (91.63%)

11186449.94 hits per line

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

95.45
/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/internal/ct_utils.h>
19
#include <botan/internal/tls_reader.h>
20

21
namespace Botan::TLS {
22

23
Server_Hello_Internal::Server_Hello_Internal(const std::vector<uint8_t>& buf) {
3,569✔
24
   if(buf.size() < 38) {
3,569✔
25
      throw Decoding_Error("Server_Hello: Packet corrupted");
6✔
26
   }
27

28
   TLS_Data_Reader reader("ServerHello", buf);
3,563✔
29

30
   const uint8_t major_version = reader.get_byte();
3,563✔
31
   const uint8_t minor_version = reader.get_byte();
3,563✔
32

33
   m_legacy_version = Protocol_Version(major_version, minor_version);
3,563✔
34

35
   // RFC 8446 4.1.3
36
   //    Upon receiving a message with type server_hello, implementations MUST
37
   //    first examine the Random value and, if it matches this value, process
38
   //    it as described in Section 4.1.4 [Hello Retry Request]).
39
   m_random = reader.get_fixed<uint8_t>(32);
3,563✔
40
   m_is_hello_retry_request = CT::is_equal<uint8_t>(m_random, HELLO_RETRY_REQUEST_MARKER).as_bool();
7,126✔
41

42
   m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32));
3,563✔
43
   m_ciphersuite = reader.get_uint16_t();
3,554✔
44
   m_comp_method = reader.get_byte();
3,552✔
45

46
   // Note that this code path might parse a TLS 1.2 (or older) server hello message that
47
   // is nevertheless marked as being a 'hello retry request' (potentially maliciously).
48
   // Extension parsing will however not be affected by the associated flag.
49
   // Only after parsing the extensions will the upstream code be able to decide
50
   // whether we're dealing with TLS 1.3 or older.
51
   m_extensions.deserialize(reader,
3,551✔
52
                            Connection_Side::Server,
53
                            m_is_hello_retry_request ? Handshake_Type::HelloRetryRequest : Handshake_Type::ServerHello);
3,551✔
54
}
3,873✔
55

56
Protocol_Version Server_Hello_Internal::version() const {
5,417✔
57
   // RFC 8446 4.2.1
58
   //    A server which negotiates a version of TLS prior to TLS 1.3 MUST set
59
   //    ServerHello.version and MUST NOT send the "supported_versions"
60
   //    extension.  A server which negotiates TLS 1.3 MUST respond by sending
61
   //    a "supported_versions" extension containing the selected version
62
   //    value (0x0304).
63
   //
64
   // Note: Here we just take a message parsing decision, further validation of
65
   //       the extension's contents is done later.
66
   return (extensions().has<Supported_Versions>()) ? Protocol_Version::TLS_V13 : m_legacy_version;
5,417✔
67
}
68

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

71
Server_Hello::Server_Hello(Server_Hello&&) noexcept = default;
11,596✔
72
Server_Hello& Server_Hello::operator=(Server_Hello&&) noexcept = default;
1✔
73

74
Server_Hello::~Server_Hello() = default;
16,397✔
75

76
/*
77
* Serialize a Server Hello message
78
*/
79
std::vector<uint8_t> Server_Hello::serialize() const {
1,397✔
80
   std::vector<uint8_t> buf;
1,397✔
81
   buf.reserve(1024);  // working around GCC warning
1,397✔
82

83
   buf.push_back(m_data->legacy_version().major_version());
1,397✔
84
   buf.push_back(m_data->legacy_version().minor_version());
1,397✔
85
   buf += m_data->random();
1,397✔
86

87
   append_tls_length_value(buf, m_data->session_id().get(), 1);
1,397✔
88

89
   buf.push_back(get_byte<0>(m_data->ciphersuite()));
1,397✔
90
   buf.push_back(get_byte<1>(m_data->ciphersuite()));
1,397✔
91

92
   buf.push_back(m_data->comp_method());
1,397✔
93

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

96
   return buf;
1,397✔
97
}
×
98

99
Handshake_Type Server_Hello::type() const {
7,382✔
100
   return Handshake_Type::ServerHello;
7,382✔
101
}
102

103
Protocol_Version Server_Hello::legacy_version() const {
13,962✔
104
   return m_data->legacy_version();
13,962✔
105
}
106

107
const std::vector<uint8_t>& Server_Hello::random() const {
3,820✔
108
   return m_data->random();
3,820✔
109
}
110

111
uint8_t Server_Hello::compression_method() const {
6,512✔
112
   return m_data->comp_method();
6,512✔
113
}
114

115
const Session_ID& Server_Hello::session_id() const {
6,911✔
116
   return m_data->session_id();
6,911✔
117
}
118

119
uint16_t Server_Hello::ciphersuite() const {
14,941✔
120
   return m_data->ciphersuite();
14,941✔
121
}
122

123
std::set<Extension_Code> Server_Hello::extension_types() const {
2,319✔
124
   return m_data->extensions().extension_types();
2,319✔
125
}
126

127
const Extensions& Server_Hello::extensions() const {
8,177✔
128
   return m_data->extensions();
8,177✔
129
}
130

131
Server_Hello_12_Shim::Server_Hello_12_Shim(const std::vector<uint8_t>& buf) :
2,522✔
132
      Server_Hello_12_Shim(std::make_unique<Server_Hello_Internal>(buf)) {}
2,522✔
133

134
Server_Hello_12_Shim::Server_Hello_12_Shim(std::unique_ptr<Server_Hello_Internal> data) :
3,844✔
135
      Server_Hello(std::move(data)) {
3,844✔
136
   if(!m_data->version().is_pre_tls_13()) {
7,688✔
137
      throw TLS_Exception(Alert::ProtocolVersion, "Expected server hello of (D)TLS 1.2 or lower");
×
138
   }
139
}
3,844✔
140

141
Protocol_Version Server_Hello_12_Shim::selected_version() const {
492✔
142
   return legacy_version();
492✔
143
}
144

145
std::optional<Protocol_Version> Server_Hello_12_Shim::random_signals_downgrade() const {
613✔
146
   const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
613✔
147
   if(last8 == DOWNGRADE_TLS11) {
613✔
148
      return Protocol_Version::TLS_V11;
×
149
   }
150
   if(last8 == DOWNGRADE_TLS12) {
613✔
151
      return Protocol_Version::TLS_V12;
1✔
152
   }
153

154
   return std::nullopt;
612✔
155
}
156

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