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

randombit / botan / 24107517494

07 Apr 2026 10:28PM UTC coverage: 89.436% (-0.01%) from 89.447%
24107517494

push

github

web-flow
Merge pull request #5522 from randombit/jack/various-tls-fixes

Various TLS fixes

105957 of 118472 relevant lines covered (89.44%)

11465209.16 hits per line

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

98.04
/src/lib/tls/tls12/msg_server_hello_12.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
*
7
* Botan is released under the Simplified BSD License (see license.txt)
8
*/
9

10
#include <botan/tls_messages_12.h>
11

12
#include <botan/tls_callbacks.h>
13
#include <botan/tls_extensions_12.h>
14
#include <botan/tls_policy.h>
15
#include <botan/internal/tls_handshake_hash.h>
16
#include <botan/internal/tls_handshake_io.h>
17
#include <botan/internal/tls_messages_internal.h>
18

19
namespace Botan::TLS {
20

21
// New session case
22
Server_Hello_12::Server_Hello_12(Handshake_IO& io,
740✔
23
                                 Handshake_Hash& hash,
24
                                 const Policy& policy,
25
                                 Callbacks& cb,
26
                                 RandomNumberGenerator& rng,
27
                                 const std::vector<uint8_t>& reneg_info,
28
                                 const Client_Hello_12& client_hello,
29
                                 const Server_Hello_12::Settings& server_settings,
30
                                 std::string_view next_protocol) :
740✔
31
      Server_Hello_12(std::make_unique<Server_Hello_Internal>(
740✔
32
         server_settings.protocol_version(),
1,480✔
33
         server_settings.session_id(),
740✔
34
         make_server_hello_random(rng, server_settings.protocol_version(), cb, policy),
740✔
35
         server_settings.ciphersuite(),
740✔
36
         uint8_t(0))) {
1,480✔
37
   // NOLINTBEGIN(*-owning-memory)
38
   if(client_hello.supports_extended_master_secret()) {
740✔
39
      m_data->extensions().add(new Extended_Master_Secret);
735✔
40
   }
41

42
   // Sending the extension back does not commit us to sending a stapled response
43
   if(client_hello.supports_cert_status_message() && policy.support_cert_status_message()) {
740✔
44
      m_data->extensions().add(new Certificate_Status_Request);
206✔
45
   }
46

47
   if(!next_protocol.empty() && client_hello.supports_alpn()) {
740✔
48
      m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol));
126✔
49
   }
50

51
   const auto c = Ciphersuite::by_id(m_data->ciphersuite());
740✔
52

53
   if(c && c->cbc_ciphersuite() && client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) {
740✔
54
      m_data->extensions().add(new Encrypt_then_MAC);
14✔
55
   }
56

57
   if(c && c->ecc_ciphersuite() && client_hello.extension_types().contains(Extension_Code::EcPointFormats)) {
2,121✔
58
      m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
640✔
59
   }
60

61
   if(client_hello.secure_renegotiation()) {
740✔
62
      m_data->extensions().add(new Renegotiation_Extension(reneg_info));
737✔
63
   }
64

65
   if(client_hello.supports_session_ticket() && server_settings.offer_session_ticket()) {
740✔
66
      m_data->extensions().add(new Session_Ticket_Extension());
543✔
67
   }
68

69
   if(m_data->legacy_version().is_datagram_protocol()) {
740✔
70
      const std::vector<uint16_t> server_srtp = policy.srtp_profiles();
292✔
71
      const std::vector<uint16_t> client_srtp = client_hello.srtp_profiles();
292✔
72

73
      if(!server_srtp.empty() && !client_srtp.empty()) {
292✔
74
         uint16_t shared = 0;
75
         // always using server preferences for now
76
         for(auto s_srtp : server_srtp) {
6✔
77
            for(auto c_srtp : client_srtp) {
16✔
78
               if(shared == 0 && s_srtp == c_srtp) {
12✔
79
                  shared = s_srtp;
1✔
80
               }
81
            }
82
         }
83

84
         if(shared != 0) {
2✔
85
            m_data->extensions().add(new SRTP_Protection_Profiles(shared));
1✔
86
         }
87
      }
88
   }
294✔
89
   // NOLINTEND(*-owning-memory)
90

91
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
740✔
92

93
   hash.update(io.send(*this));
1,480✔
94
}
740✔
95

96
// Resuming
97
Server_Hello_12::Server_Hello_12(Handshake_IO& io,
229✔
98
                                 Handshake_Hash& hash,
99
                                 const Policy& policy,
100
                                 Callbacks& cb,
101
                                 RandomNumberGenerator& rng,
102
                                 const std::vector<uint8_t>& reneg_info,
103
                                 const Client_Hello_12& client_hello,
104
                                 const Session& resumed_session,
105
                                 bool offer_session_ticket,
106
                                 std::string_view next_protocol) :
229✔
107
      Server_Hello_12(
108
         std::make_unique<Server_Hello_Internal>(resumed_session.version(),
458✔
109
                                                 client_hello.session_id(),
229✔
110
                                                 make_server_hello_random(rng, resumed_session.version(), cb, policy),
229✔
111
                                                 resumed_session.ciphersuite_code(),
458✔
112
                                                 uint8_t(0))) {
458✔
113
   // NOLINTBEGIN(*-owning-memory)
114
   if(client_hello.supports_extended_master_secret()) {
229✔
115
      m_data->extensions().add(new Extended_Master_Secret);
228✔
116
   }
117

118
   if(!next_protocol.empty() && client_hello.supports_alpn()) {
229✔
119
      m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol));
14✔
120
   }
121

122
   if(client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) {
229✔
123
      const Ciphersuite c = resumed_session.ciphersuite();
2✔
124
      if(c.cbc_ciphersuite()) {
2✔
125
         m_data->extensions().add(new Encrypt_then_MAC);
2✔
126
      }
127
   }
128

129
   if(resumed_session.ciphersuite().ecc_ciphersuite() &&
229✔
130
      client_hello.extension_types().contains(Extension_Code::EcPointFormats)) {
643✔
131
      m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
207✔
132
   }
133

134
   if(client_hello.secure_renegotiation()) {
229✔
135
      m_data->extensions().add(new Renegotiation_Extension(reneg_info));
229✔
136
   }
137

138
   if(client_hello.supports_session_ticket() && offer_session_ticket) {
229✔
139
      m_data->extensions().add(new Session_Ticket_Extension());
1✔
140
   }
141
   // NOLINTEND(*-owning-memory)
142

143
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
229✔
144

145
   hash.update(io.send(*this));
458✔
146
}
229✔
147

148
Server_Hello_12::Server_Hello_12(const std::vector<uint8_t>& buf) :
3,080✔
149
      Server_Hello_12(std::make_unique<Server_Hello_Internal>(buf)) {}
3,080✔
150

151
Server_Hello_12::Server_Hello_12(std::unique_ptr<Server_Hello_Internal> data) : Server_Hello_12_Shim(std::move(data)) {}
3,871✔
152

153
bool Server_Hello_12::secure_renegotiation() const {
3,720✔
154
   return m_data->extensions().has<Renegotiation_Extension>();
3,720✔
155
}
156

157
std::vector<uint8_t> Server_Hello_12::renegotiation_info() const {
3,626✔
158
   if(const Renegotiation_Extension* reneg = m_data->extensions().get<Renegotiation_Extension>()) {
3,626✔
159
      return reneg->renegotiation_info();
3,626✔
160
   }
161
   return std::vector<uint8_t>();
×
162
}
163

164
bool Server_Hello_12::supports_extended_master_secret() const {
3,950✔
165
   return m_data->extensions().has<Extended_Master_Secret>();
3,950✔
166
}
167

168
bool Server_Hello_12::supports_encrypt_then_mac() const {
7,324✔
169
   return m_data->extensions().has<Encrypt_then_MAC>();
7,324✔
170
}
171

172
bool Server_Hello_12::supports_certificate_status_message() const {
1,908✔
173
   return m_data->extensions().has<Certificate_Status_Request>();
1,908✔
174
}
175

176
bool Server_Hello_12::supports_session_ticket() const {
2,622✔
177
   return m_data->extensions().has<Session_Ticket_Extension>();
2,622✔
178
}
179

180
uint16_t Server_Hello_12::srtp_profile() const {
4,235✔
181
   if(auto* srtp = m_data->extensions().get<SRTP_Protection_Profiles>()) {
4,235✔
182
      auto prof = srtp->profiles();
4✔
183
      if(prof.size() != 1 || prof[0] == 0) {
4✔
184
         throw Decoding_Error("Server sent malformed DTLS-SRTP extension");
×
185
      }
186
      return prof[0];
4✔
187
   }
4✔
188

189
   return 0;
190
}
191

192
std::string Server_Hello_12::next_protocol() const {
2,676✔
193
   if(auto* alpn = m_data->extensions().get<Application_Layer_Protocol_Notification>()) {
2,676✔
194
      return alpn->single_protocol();
141✔
195
   }
196
   return "";
2,535✔
197
}
198

199
bool Server_Hello_12::prefers_compressed_ec_points() const {
25✔
200
   if(auto* ecc_formats = m_data->extensions().get<Supported_Point_Formats>()) {
25✔
201
      return ecc_formats->prefers_compressed();
13✔
202
   }
203
   return false;
204
}
205

206
/*
207
* Create a new Server Hello Done message
208
*/
209
Server_Hello_Done::Server_Hello_Done(Handshake_IO& io, Handshake_Hash& hash) {
715✔
210
   hash.update(io.send(*this));
1,430✔
211
}
715✔
212

213
/*
214
* Deserialize a Server Hello Done message
215
*/
216
Server_Hello_Done::Server_Hello_Done(const std::vector<uint8_t>& buf) {
854✔
217
   if(!buf.empty()) {
854✔
218
      throw Decoding_Error("Server_Hello_Done: Must be empty, and is not");
2✔
219
   }
220
}
852✔
221

222
/*
223
* Serialize a Server Hello Done message
224
*/
225
std::vector<uint8_t> Server_Hello_Done::serialize() const {
715✔
226
   return std::vector<uint8_t>();
715✔
227
}
228

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