Coverage Report

Created: 2025-04-11 06:34

/src/botan/src/lib/tls/tls12/tls_handshake_state.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* TLS Handshaking
3
* (C) 2004-2006,2011,2012,2015,2016 Jack Lloyd
4
*     2017 Harry Reimann, Rohde & Schwarz Cybersecurity
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
#include <botan/internal/tls_handshake_state.h>
10
11
#include <botan/kdf.h>
12
#include <botan/tls_messages.h>
13
#include <botan/tls_signature_scheme.h>
14
#include <botan/internal/tls_record.h>
15
#include <sstream>
16
17
namespace Botan::TLS {
18
19
0
std::string Handshake_Message::type_string() const {
20
0
   return handshake_type_to_string(type());
21
0
}
22
23
543
const char* handshake_type_to_string(Handshake_Type type) {
24
543
   switch(type) {
25
16
      case Handshake_Type::HelloVerifyRequest:
26
16
         return "hello_verify_request";
27
28
60
      case Handshake_Type::HelloRequest:
29
60
         return "hello_request";
30
31
170
      case Handshake_Type::ClientHello:
32
170
         return "client_hello";
33
34
69
      case Handshake_Type::ServerHello:
35
69
         return "server_hello";
36
37
9
      case Handshake_Type::HelloRetryRequest:
38
9
         return "hello_retry_request";
39
40
15
      case Handshake_Type::Certificate:
41
15
         return "certificate";
42
43
9
      case Handshake_Type::CertificateUrl:
44
9
         return "certificate_url";
45
46
6
      case Handshake_Type::CertificateStatus:
47
6
         return "certificate_status";
48
49
7
      case Handshake_Type::ServerKeyExchange:
50
7
         return "server_key_exchange";
51
52
10
      case Handshake_Type::CertificateRequest:
53
10
         return "certificate_request";
54
55
10
      case Handshake_Type::ServerHelloDone:
56
10
         return "server_hello_done";
57
58
12
      case Handshake_Type::CertificateVerify:
59
12
         return "certificate_verify";
60
61
54
      case Handshake_Type::ClientKeyExchange:
62
54
         return "client_key_exchange";
63
64
12
      case Handshake_Type::NewSessionTicket:
65
12
         return "new_session_ticket";
66
67
53
      case Handshake_Type::HandshakeCCS:
68
53
         return "change_cipher_spec";
69
70
13
      case Handshake_Type::Finished:
71
13
         return "finished";
72
73
5
      case Handshake_Type::EndOfEarlyData:
74
5
         return "end_of_early_data";
75
76
5
      case Handshake_Type::EncryptedExtensions:
77
5
         return "encrypted_extensions";
78
79
8
      case Handshake_Type::KeyUpdate:
80
8
         return "key_update";
81
82
0
      case Handshake_Type::None:
83
0
         return "invalid";
84
543
   }
85
86
0
   throw TLS_Exception(Alert::UnexpectedMessage,
87
0
                       "Unknown TLS handshake message type " + std::to_string(static_cast<size_t>(type)));
88
543
}
89
90
/*
91
* Initialize the SSL/TLS Handshake State
92
*/
93
29.4k
Handshake_State::~Handshake_State() = default;
94
95
Handshake_State::Handshake_State(std::unique_ptr<Handshake_IO> io, Callbacks& cb) :
96
29.4k
      m_callbacks(cb), m_handshake_io(std::move(io)), m_version(m_handshake_io->initial_record_version()) {}
97
98
99.2k
void Handshake_State::note_message(const Handshake_Message& msg) {
99
99.2k
   m_callbacks.tls_inspect_handshake_msg(msg);
100
99.2k
}
101
102
0
void Handshake_State::hello_verify_request(const Hello_Verify_Request& hello_verify) {
103
0
   note_message(hello_verify);
104
105
0
   m_client_hello->update_hello_cookie(hello_verify);
106
0
   hash().reset();
107
0
   hash().update(handshake_io().send(*m_client_hello));
108
0
   note_message(*m_client_hello);
109
0
}
110
111
34.8k
void Handshake_State::client_hello(Client_Hello_12* client_hello) {
112
34.8k
   if(client_hello == nullptr) {
113
5.23k
      m_client_hello.reset();
114
5.23k
      hash().reset();
115
29.6k
   } else {
116
29.6k
      m_client_hello.reset(client_hello);
117
29.6k
      note_message(*m_client_hello);
118
29.6k
   }
119
34.8k
}
120
121
21.3k
void Handshake_State::server_hello(Server_Hello_12* server_hello) {
122
21.3k
   m_server_hello.reset(server_hello);
123
21.3k
   m_ciphersuite = Ciphersuite::by_id(m_server_hello->ciphersuite());
124
21.3k
   note_message(*m_server_hello);
125
21.3k
}
126
127
9
void Handshake_State::server_certs(Certificate_12* server_certs) {
128
9
   m_server_certs.reset(server_certs);
129
9
   note_message(*m_server_certs);
130
9
}
131
132
0
void Handshake_State::server_cert_status(Certificate_Status* server_cert_status) {
133
0
   m_server_cert_status.reset(server_cert_status);
134
0
   note_message(*m_server_cert_status);
135
0
}
136
137
21.1k
void Handshake_State::server_kex(Server_Key_Exchange* server_kex) {
138
21.1k
   m_server_kex.reset(server_kex);
139
21.1k
   note_message(*m_server_kex);
140
21.1k
}
141
142
0
void Handshake_State::cert_req(Certificate_Request_12* cert_req) {
143
0
   m_cert_req.reset(cert_req);
144
0
   note_message(*m_cert_req);
145
0
}
146
147
21.1k
void Handshake_State::server_hello_done(Server_Hello_Done* server_hello_done) {
148
21.1k
   m_server_hello_done.reset(server_hello_done);
149
21.1k
   note_message(*m_server_hello_done);
150
21.1k
}
151
152
0
void Handshake_State::client_certs(Certificate_12* client_certs) {
153
0
   m_client_certs.reset(client_certs);
154
0
   note_message(*m_client_certs);
155
0
}
156
157
5.49k
void Handshake_State::client_kex(Client_Key_Exchange* client_kex) {
158
5.49k
   m_client_kex.reset(client_kex);
159
5.49k
   note_message(*m_client_kex);
160
5.49k
}
161
162
0
void Handshake_State::client_verify(Certificate_Verify_12* client_verify) {
163
0
   m_client_verify.reset(client_verify);
164
0
   note_message(*m_client_verify);
165
0
}
166
167
0
void Handshake_State::server_verify(Certificate_Verify_12* server_verify) {
168
0
   m_server_verify.reset(server_verify);
169
0
   note_message(*m_server_verify);
170
0
}
171
172
0
void Handshake_State::new_session_ticket(New_Session_Ticket_12* new_session_ticket) {
173
0
   m_new_session_ticket.reset(new_session_ticket);
174
0
   note_message(*m_new_session_ticket);
175
0
}
176
177
244
void Handshake_State::server_finished(Finished_12* server_finished) {
178
244
   m_server_finished.reset(server_finished);
179
244
   note_message(*m_server_finished);
180
244
}
181
182
244
void Handshake_State::client_finished(Finished_12* client_finished) {
183
244
   m_client_finished.reset(client_finished);
184
244
   note_message(*m_client_finished);
185
244
}
186
187
94.8k
const Ciphersuite& Handshake_State::ciphersuite() const {
188
94.8k
   if(!m_ciphersuite.has_value()) {
189
0
      throw Invalid_State("Cipher suite is not set");
190
0
   }
191
94.8k
   return m_ciphersuite.value();
192
94.8k
}
193
194
244
std::optional<std::string> Handshake_State::psk_identity() const {
195
244
   if(!m_client_kex) {
196
0
      return std::nullopt;
197
0
   }
198
244
   return m_client_kex->psk_identity();
199
244
}
200
201
26.7k
void Handshake_State::set_version(const Protocol_Version& version) {
202
26.7k
   m_version = version;
203
26.7k
}
204
205
5.49k
void Handshake_State::compute_session_keys() {
206
5.49k
   m_session_keys = Session_Keys(this, client_kex()->pre_master_secret(), false);
207
5.49k
}
208
209
0
void Handshake_State::compute_session_keys(const secure_vector<uint8_t>& resume_master_secret) {
210
0
   m_session_keys = Session_Keys(this, resume_master_secret, true);
211
0
}
212
213
36.7k
void Handshake_State::confirm_transition_to(Handshake_Type handshake_msg) {
214
36.7k
   m_transitions.confirm_transition_to(handshake_msg);
215
36.7k
}
216
217
61.3k
void Handshake_State::set_expected_next(Handshake_Type handshake_msg) {
218
61.3k
   m_transitions.set_expected_next(handshake_msg);
219
61.3k
}
220
221
6.49k
bool Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) const {
222
6.49k
   return m_transitions.received_handshake_msg(handshake_msg);
223
6.49k
}
224
225
78.9k
std::pair<Handshake_Type, std::vector<uint8_t>> Handshake_State::get_next_handshake_msg() {
226
78.9k
   return m_handshake_io->get_next_record(m_transitions.change_cipher_spec_expected());
227
78.9k
}
228
229
0
Session_Ticket Handshake_State::session_ticket() const {
230
0
   if(new_session_ticket() && !new_session_ticket()->ticket().empty()) {
231
0
      return new_session_ticket()->ticket();
232
0
   }
233
234
0
   return client_hello()->session_ticket();
235
0
}
236
237
5.97k
std::unique_ptr<KDF> Handshake_State::protocol_specific_prf() const {
238
5.97k
   const std::string prf_algo = ciphersuite().prf_algo();
239
240
5.97k
   if(prf_algo == "MD5" || prf_algo == "SHA-1") {
241
1.01k
      return KDF::create_or_throw("TLS-12-PRF(SHA-256)");
242
1.01k
   }
243
244
4.96k
   return KDF::create_or_throw("TLS-12-PRF(" + prf_algo + ")");
245
5.97k
}
246
247
std::pair<std::string, Signature_Format> Handshake_State::choose_sig_format(const Private_Key& key,
248
                                                                            Signature_Scheme& chosen_scheme,
249
                                                                            bool for_client_auth,
250
0
                                                                            const Policy& policy) const {
251
0
   const std::string sig_algo = key.algo_name();
252
253
0
   const std::vector<Signature_Scheme> allowed = policy.allowed_signature_schemes();
254
255
0
   std::vector<Signature_Scheme> requested =
256
0
      (for_client_auth) ? cert_req()->signature_schemes() : client_hello()->signature_schemes();
257
258
0
   for(Signature_Scheme scheme : allowed) {
259
0
      if(!scheme.is_available()) {
260
0
         continue;
261
0
      }
262
263
0
      if(scheme.algorithm_name() == sig_algo) {
264
0
         if(std::find(requested.begin(), requested.end(), scheme) != requested.end()) {
265
0
            chosen_scheme = scheme;
266
0
            break;
267
0
         }
268
0
      }
269
0
   }
270
271
0
   const std::string hash = chosen_scheme.hash_function_name();
272
273
0
   if(!policy.allowed_signature_hash(hash)) {
274
0
      throw TLS_Exception(Alert::HandshakeFailure, "Policy refuses to accept signing with any hash supported by peer");
275
0
   }
276
277
0
   if(!chosen_scheme.format().has_value()) {
278
0
      throw Invalid_Argument(sig_algo + " is invalid/unknown for TLS signatures");
279
0
   }
280
281
0
   return std::make_pair(chosen_scheme.padding_string(), chosen_scheme.format().value());
282
0
}
283
284
namespace {
285
286
bool supported_algos_include(const std::vector<Signature_Scheme>& schemes,
287
                             std::string_view key_type,
288
0
                             std::string_view hash_type) {
289
0
   for(Signature_Scheme scheme : schemes) {
290
0
      if(scheme.is_available() && hash_type == scheme.hash_function_name() && key_type == scheme.algorithm_name()) {
291
0
         return true;
292
0
      }
293
0
   }
294
295
0
   return false;
296
0
}
297
298
}  // namespace
299
300
std::pair<std::string, Signature_Format> Handshake_State::parse_sig_format(
301
   const Public_Key& key,
302
   Signature_Scheme scheme,
303
   const std::vector<Signature_Scheme>& offered_schemes,
304
   bool for_client_auth,
305
0
   const Policy& policy) const {
306
0
   const std::string key_type = key.algo_name();
307
308
0
   if(!policy.allowed_signature_method(key_type)) {
309
0
      throw TLS_Exception(Alert::HandshakeFailure, "Rejecting " + key_type + " signature");
310
0
   }
311
312
0
   if(!scheme.is_available()) {
313
0
      throw TLS_Exception(Alert::IllegalParameter, "Peer sent unknown signature scheme");
314
0
   }
315
316
0
   if(key_type != scheme.algorithm_name()) {
317
0
      throw Decoding_Error("Counterparty sent inconsistent key and sig types");
318
0
   }
319
320
0
   if(for_client_auth && !cert_req()) {
321
0
      throw TLS_Exception(Alert::HandshakeFailure, "No certificate verify set");
322
0
   }
323
324
   /*
325
   Confirm the signature type we just received against the
326
   supported_algos list that we sent; it better be there.
327
   */
328
329
0
   const std::vector<Signature_Scheme> supported_algos =
330
0
      for_client_auth ? cert_req()->signature_schemes() : offered_schemes;
331
332
0
   const std::string hash_algo = scheme.hash_function_name();
333
334
0
   if(!scheme.is_compatible_with(Protocol_Version::TLS_V12)) {
335
0
      throw TLS_Exception(Alert::IllegalParameter, "Peer sent unexceptable signature scheme");
336
0
   }
337
338
0
   if(!supported_algos_include(supported_algos, key_type, hash_algo)) {
339
0
      throw TLS_Exception(Alert::IllegalParameter,
340
0
                          "TLS signature extension did not allow for " + key_type + "/" + hash_algo + " signature");
341
0
   }
342
343
0
   if(!scheme.format().has_value()) {
344
0
      throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures");
345
0
   }
346
347
0
   return std::make_pair(scheme.padding_string(), scheme.format().value());
348
0
}
349
350
}  // namespace Botan::TLS