Botan 3.13.0
Crypto and TLS for C&
tls_client_impl_12.cpp
Go to the documentation of this file.
1/*
2* TLS Client
3* (C) 2004-2011,2012,2015,2016 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/internal/tls_client_impl_12.h>
11
12#include <botan/ocsp.h>
13#include <botan/tls_callbacks.h>
14#include <botan/tls_messages_12.h>
15#include <botan/tls_policy.h>
16#include <botan/internal/stl_util.h>
17#include <botan/internal/tls_handshake_state.h>
18#include <algorithm>
19#include <optional>
20#include <sstream>
21#include <utility>
22
23namespace Botan::TLS {
24
25namespace {
26
27class Client_Handshake_State_12 final : public Handshake_State {
28 public:
29 Client_Handshake_State_12(std::unique_ptr<Handshake_IO> io, Callbacks& cb) :
30 Handshake_State(std::move(io), cb), m_is_reneg(false) {}
31
32 const Public_Key& server_public_key() const {
33 BOTAN_ASSERT(m_server_public_key, "Server sent us a certificate");
34 return *m_server_public_key;
35 }
36
37 const Public_Key* maybe_server_public_key() const { return m_server_public_key.get(); }
38
39 void record_server_public_key(std::unique_ptr<Public_Key> spk) {
40 BOTAN_STATE_CHECK(!m_server_public_key);
41 m_server_public_key = std::move(spk);
42 }
43
44 bool is_a_resumption() const { return m_resumed_session.has_value(); }
45
46 void discard_resumption_state() { m_resumed_session.reset(); }
47
48 void record_resumption_info(std::optional<Session> session_info) {
49 BOTAN_STATE_CHECK(!m_resumed_session.has_value());
50 m_resumed_session = std::move(session_info);
51 }
52
53 bool is_a_renegotiation() const { return m_is_reneg; }
54
55 void mark_as_renegotiation() { m_is_reneg = true; }
56
57 size_t note_hello_verify_request() { return ++m_hello_verify_requests; }
58
59 const secure_vector<uint8_t>& resume_master_secret() const {
60 BOTAN_STATE_CHECK(is_a_resumption());
61 return m_resumed_session->master_secret();
62 }
63
64 const std::vector<X509_Certificate>& resume_peer_certs() const {
65 BOTAN_STATE_CHECK(is_a_resumption());
66 return m_resumed_session->peer_certs();
67 }
68
69 bool resumed_session_supports_extended_master_secret() const {
70 BOTAN_STATE_CHECK(is_a_resumption());
71 return m_resumed_session->supports_extended_master_secret();
72 }
73
74 uint16_t resumed_session_ciphersuite_code() const {
75 BOTAN_STATE_CHECK(is_a_resumption());
76 return m_resumed_session->ciphersuite_code();
77 }
78
79 std::vector<X509_Certificate> peer_cert_chain() const override {
80 if(is_a_resumption()) {
81 return resume_peer_certs();
82 }
83 if(server_certs() != nullptr) {
84 return server_certs()->cert_chain();
85 }
86 return {};
87 }
88
89 private:
90 std::unique_ptr<Public_Key> m_server_public_key;
91
92 // Used during session resumption
93 std::optional<Session> m_resumed_session;
94 bool m_is_reneg = false;
95 size_t m_hello_verify_requests = 0;
96};
97
98} // namespace
99
100/*
101* TLS 1.2 Client Constructor
102*/
103Client_Impl_12::Client_Impl_12(const std::shared_ptr<Callbacks>& callbacks,
104 const std::shared_ptr<Session_Manager>& session_manager,
105 const std::shared_ptr<Credentials_Manager>& creds,
106 const std::shared_ptr<const Policy>& policy,
107 const std::shared_ptr<RandomNumberGenerator>& rng,
109 bool datagram,
110 const std::vector<std::string>& next_protocols,
111 size_t io_buf_sz) :
112 Channel_Impl_12(callbacks, session_manager, rng, policy, false, datagram, io_buf_sz),
113 m_creds(creds),
114 m_info(std::move(info)) {
115 BOTAN_ASSERT_NONNULL(m_creds);
116 const auto version = datagram ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
117 Handshake_State& state = create_handshake_state(version);
118 send_client_hello(state, false, version, std::nullopt /* no a-priori session to resume */, next_protocols);
119}
120
121#if defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
122
123Client_Impl_12::Client_Impl_12(Channel_Impl::Downgrade_Information& downgrade_info) :
124 Channel_Impl_12(downgrade_info.callbacks,
125 downgrade_info.session_manager,
126 downgrade_info.rng,
127 downgrade_info.policy,
128 false /* is_server */,
129 false /* datagram -- not supported by Botan in TLS 1.3 */,
130 downgrade_info.io_buffer_size),
131 m_creds(downgrade_info.creds),
132 m_info(downgrade_info.server_info) {
133 Handshake_State& state = create_handshake_state(Protocol_Version::TLS_V12);
134
135 if(downgrade_info.client_hello.has_value()) {
136 // Downgrade detected after receiving a TLS 1.2 server hello. We need to
137 // recreate the state as if this implementation issued the client hello.
138
139 state.client_hello(std::make_unique<Client_Hello_12>(
140 std::exchange(downgrade_info.client_hello, {}).value(), state.handshake_io(), state.hash()));
141
144 } else {
145 // Downgrade initiated after a TLS 1.2 session was found. No communication
146 // has happened yet but the found session should be used for resumption.
147 BOTAN_ASSERT_NOMSG(downgrade_info.tls12_session.has_value() &&
148 downgrade_info.tls12_session->session.version().is_pre_tls_13());
149 send_client_hello(state,
150 false,
151 downgrade_info.tls12_session->session.version(),
152 downgrade_info.tls12_session,
153 downgrade_info.next_protocols);
154 }
155}
156
157#endif
158
159std::unique_ptr<Handshake_State> Client_Impl_12::new_handshake_state(std::unique_ptr<Handshake_IO> io) {
160 return std::make_unique<Client_Handshake_State_12>(std::move(io), callbacks());
161}
162
163/*
164* Send a new client hello to renegotiate
165*/
166void Client_Impl_12::initiate_handshake(Handshake_State& state, bool force_full_renegotiation) {
167 // we don't support TLS < 1.2 anymore and TLS 1.3 should not use this client impl
168 const auto version = state.version().is_datagram_protocol() ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
169 send_client_hello(state, force_full_renegotiation, version);
170}
171
172void Client_Impl_12::send_client_hello(Handshake_State& state_base,
173 bool force_full_renegotiation,
174 Protocol_Version version,
175 std::optional<Session_with_Handle> session_and_handle,
176 const std::vector<std::string>& next_protocols) {
177 Client_Handshake_State_12& state = dynamic_cast<Client_Handshake_State_12&>(state_base);
178
179 if(state.version().is_datagram_protocol()) {
180 state.set_expected_next(Handshake_Type::HelloVerifyRequest); // optional
181 }
182 state.set_expected_next(Handshake_Type::ServerHello);
183
184 if(!force_full_renegotiation) {
185 // if no session is provided, we need to try and find one opportunistically
186 if(!session_and_handle.has_value() && !m_info.empty()) {
187 if(auto sessions = session_manager().find(m_info, callbacks(), policy()); !sessions.empty()) {
188 session_and_handle = std::move(sessions.front());
189 }
190 }
191
192 if(session_and_handle.has_value()) {
193 /*
194 Ensure that the session protocol cipher and version are acceptable
195 If not skip the resume and establish a new session
196 */
197 auto& session_info = session_and_handle->session;
198 const bool exact_version = session_info.version() == version;
199 const bool ok_version = (session_info.version().is_datagram_protocol() == version.is_datagram_protocol()) &&
200 policy().acceptable_protocol_version(session_info.version());
201
202 const bool session_version_ok = policy().only_resume_with_exact_version() ? exact_version : ok_version;
203
204 if(policy().acceptable_ciphersuite(session_info.ciphersuite()) && session_version_ok) {
205 state.client_hello(std::make_unique<Client_Hello_12>(state.handshake_io(),
206 state.hash(),
207 policy(),
208 callbacks(),
209 rng(),
211 session_and_handle.value(),
212 next_protocols));
213
214 state.record_resumption_info(std::move(session_info));
215 }
216 }
217 }
218
219 if(state.client_hello() == nullptr) {
220 // not resuming
221 const Client_Hello_12::Settings client_settings(version, m_info.hostname());
222 state.client_hello(std::make_unique<Client_Hello_12>(state.handshake_io(),
223 state.hash(),
224 policy(),
225 callbacks(),
226 rng(),
228 client_settings,
229 next_protocols));
230 }
231
232 secure_renegotiation_check(state.client_hello());
233}
234
235namespace {
236
237bool key_usage_matches_ciphersuite(Key_Constraints usage, const Ciphersuite& suite) {
238 if(usage == Key_Constraints::None) {
239 return true; // anything goes ...
240 }
241
242 if(suite.kex_method() == Kex_Algo::STATIC_RSA) {
244 } else {
246 }
247}
248
249} // namespace
250
251/*
252* Process a handshake message
253*/
254void Client_Impl_12::process_handshake_msg(Handshake_State& state_base,
255 Handshake_Type type,
256 const std::vector<uint8_t>& contents,
257 bool epoch0_restart) {
258 BOTAN_ASSERT_NOMSG(epoch0_restart == false); // only happens on server side
259
260 Client_Handshake_State_12& state = dynamic_cast<Client_Handshake_State_12&>(state_base);
261
262 if(type == Handshake_Type::HelloRequest && active_state().has_value()) {
263 const Hello_Request hello_request(contents);
264
265 // RFC 5246 Section 7.4.1.1
266 // This message will be ignored by the client if the client is
267 // currently negotiating a session.
268 if(state.client_hello() != nullptr) {
269 return;
270 }
271
272 if(policy().allow_server_initiated_renegotiation()) {
273 if(secure_renegotiation_supported() || policy().allow_insecure_renegotiation()) {
274 state.mark_as_renegotiation();
275 initiate_handshake(state, true /* force_full_renegotiation */);
276 } else {
277 throw TLS_Exception(Alert::HandshakeFailure, "Client policy prohibits insecure renegotiation");
278 }
279 } else {
280 if(policy().abort_connection_on_undesired_renegotiation()) {
281 throw TLS_Exception(Alert::NoRenegotiation, "Client policy prohibits renegotiation");
282 } else {
283 // RFC 5746 section 4.2
284 send_warning_alert(Alert::NoRenegotiation);
285 }
286 }
287
288 return;
289 }
290
291 state.confirm_transition_to(type);
292
295 state.hash().update(state.handshake_io().format(contents, type));
296 }
297
299 // RFC 6347 4.2.1 requires tolerating more than one: "This may result in
300 // clients receiving multiple HelloVerifyRequest messages with different
301 // cookies. Clients SHOULD handle this by sending a new ClientHello with a
302 // cookie in response to the new HelloVerifyRequest."
303 //
304 // Each one makes us re-send the ClientHello, and a HelloVerifyRequest is
305 // unauthenticated epoch-zero data that resets the retransmission counter,
306 // so an unbounded stream of forged ones would have us flood the server
307 // indefinitely. Bound how many we will act on.
308 const size_t hello_verify_requests = state.note_hello_verify_request();
309 const std::optional<size_t> max_hello_verify_requests = policy().dtls_maximum_hello_verify_requests();
310
311 if(max_hello_verify_requests.has_value() && hello_verify_requests > max_hello_verify_requests.value()) {
312 throw TLS_Exception(Alert::UnexpectedMessage, "Too many DTLS HelloVerifyRequest messages");
313 }
314
315 state.set_expected_next(Handshake_Type::ServerHello);
316 state.set_expected_next(Handshake_Type::HelloVerifyRequest); // might get it again
317
318 const Hello_Verify_Request hello_verify_request(contents);
319 state.hello_verify_request(hello_verify_request);
320 } else if(type == Handshake_Type::ServerHello) {
321 state.server_hello(std::make_unique<Server_Hello_12>(contents));
322
323 if(!state.server_hello()->legacy_version().valid()) {
324 throw TLS_Exception(Alert::ProtocolVersion, "Server replied with an invalid version");
325 }
326
327 if(!state.client_hello()->offered_suite(state.server_hello()->ciphersuite())) {
328 throw TLS_Exception(Alert::HandshakeFailure, "Server replied with ciphersuite we didn't send");
329 }
330
331 const auto suite = Ciphersuite::by_id(state.server_hello()->ciphersuite());
332 if(!suite || !suite->usable_in_version(state.server_hello()->legacy_version())) {
333 throw TLS_Exception(Alert::HandshakeFailure,
334 "Server replied using a ciphersuite not allowed in version it offered");
335 }
336
337 // RFC 7366 3.:
338 // If a server receives an encrypt-then-MAC request extension from a client
339 // and then selects a stream or Authenticated Encryption with Associated
340 // Data (AEAD) ciphersuite, it MUST NOT send an encrypt-then-MAC
341 // response extension back to the client.
342 if(suite->aead_ciphersuite() && state.server_hello()->supports_encrypt_then_mac()) {
343 throw TLS_Exception(Alert::IllegalParameter,
344 "Server replied using an AEAD ciphersuite and an encrypt-then-MAC response extension");
345 }
346
347 if(Ciphersuite::is_scsv(state.server_hello()->ciphersuite())) {
348 throw TLS_Exception(Alert::HandshakeFailure, "Server replied with a signaling ciphersuite");
349 }
350
351 if(state.server_hello()->compression_method() != 0) {
352 throw TLS_Exception(Alert::IllegalParameter, "Server replied with non-null compression method");
353 }
354
355 if(state.client_hello()->legacy_version() > state.server_hello()->legacy_version()) {
356 // check for downgrade attacks
357 //
358 // RFC 8446 4.1.3.:
359 // TLS 1.2 clients SHOULD also check that the last 8 bytes are
360 // not equal to the [magic value DOWNGRADE_TLS11] if the ServerHello
361 // indicates TLS 1.1 or below. If a match is found, the client MUST
362 // abort the handshake with an "illegal_parameter" alert.
363 //
364 // TLS 1.3 servers will still set the magic string to DOWNGRADE_TLS12. Don't abort in this case.
365 if(auto requested = state.server_hello()->random_signals_downgrade();
366 requested.has_value() && requested.value() <= Protocol_Version::TLS_V11) {
367 throw TLS_Exception(Alert::IllegalParameter, "Downgrade attack detected");
368 }
369 }
370
371 auto client_extn = state.client_hello()->extension_types();
372 auto server_extn = state.server_hello()->extension_types();
373
374 std::vector<Extension_Code> diff;
375
376 std::set_difference(
377 server_extn.begin(), server_extn.end(), client_extn.begin(), client_extn.end(), std::back_inserter(diff));
378
379 if(!diff.empty()) {
380 // Server sent us back an extension we did not send!
381
382 std::ostringstream msg;
383 msg << "Server replied with unsupported extensions:";
384 for(auto&& d : diff) {
385 msg << " " << static_cast<int>(d);
386 }
387 throw TLS_Exception(Alert::UnsupportedExtension, msg.str());
388 }
389
390 if(const uint16_t srtp = state.server_hello()->srtp_profile()) {
391 if(!value_exists(state.client_hello()->srtp_profiles(), srtp)) {
392 throw TLS_Exception(Alert::HandshakeFailure, "Server replied with DTLS-SRTP alg we did not send");
393 }
394 }
395
397 state.server_hello()->extensions(), Connection_Side::Server, Handshake_Type::ServerHello);
398
399 state.set_version(state.server_hello()->legacy_version());
400
401 if(state.server_hello()->extensions().has<Application_Layer_Protocol_Notification>()) {
402 const auto* server_alpn = state.server_hello()->extensions().get<Application_Layer_Protocol_Notification>();
403 const auto selected = server_alpn->single_protocol();
404 const auto* client_alpn = state.client_hello()->extensions().get<Application_Layer_Protocol_Notification>();
405 BOTAN_ASSERT_NONNULL(client_alpn);
406 const auto& offered = client_alpn->protocols();
407 if(!value_exists(offered, selected)) {
408 throw TLS_Exception(Alert::IllegalParameter, "Server selected an ALPN protocol not offered by the client");
409 }
410 }
411 m_application_protocol = state.server_hello()->next_protocol();
412
413 secure_renegotiation_check(state.server_hello());
414
415 // RFC 7627 / RFC 9325 4.4: optionally require Extended Master Secret.
416 if(policy().require_extended_master_secret() && !state.server_hello()->supports_extended_master_secret()) {
417 throw TLS_Exception(Alert::HandshakeFailure,
418 "Policy requires the Extended Master Secret extension but the server did not send it");
419 }
420
421 const bool server_returned_same_session_id =
422 !state.server_hello()->session_id().empty() &&
423 (state.server_hello()->session_id() == state.client_hello()->session_id());
424
425 if(server_returned_same_session_id) {
426 // successful resumption
427 BOTAN_ASSERT_NOMSG(state.is_a_resumption());
428
429 /*
430 * In this case, we offered the version used in the original
431 * session, and the server must resume with the same version.
432 */
433 if(state.server_hello()->legacy_version() != state.client_hello()->legacy_version()) {
434 throw TLS_Exception(Alert::HandshakeFailure, "Server resumed session but with wrong version");
435 }
436
437 // RFC 5246 7.4.1.2: when resuming a session, the server MUST use
438 // the same cipher suite that was negotiated in the original session.
439 if(state.server_hello()->ciphersuite() != state.resumed_session_ciphersuite_code()) {
440 throw TLS_Exception(Alert::HandshakeFailure, "Server resumed session with a different ciphersuite");
441 }
442
443 if(state.server_hello()->supports_extended_master_secret() &&
444 !state.resumed_session_supports_extended_master_secret()) {
445 throw TLS_Exception(Alert::HandshakeFailure, "Server resumed session but added extended master secret");
446 }
447
448 if(!state.server_hello()->supports_extended_master_secret() &&
449 state.resumed_session_supports_extended_master_secret()) {
450 throw TLS_Exception(Alert::HandshakeFailure, "Server resumed session and removed extended master secret");
451 }
452
453 state.compute_session_keys(state.resume_master_secret());
454 if(policy().allow_ssl_key_log_file()) {
455 // draft-thomson-tls-keylogfile-00 Section 3.2
456 // An implementation of TLS 1.2 (and also earlier versions) use
457 // the label "CLIENT_RANDOM" to identify the "master" secret for
458 // the connection.
460 "CLIENT_RANDOM", state.client_hello()->random(), state.session_keys().master_secret());
461 }
462
463 if(state.server_hello()->supports_session_ticket()) {
464 state.set_expected_next(Handshake_Type::NewSessionTicket);
465 } else {
466 state.set_expected_next(Handshake_Type::HandshakeCCS);
467 }
468 } else {
469 // new session
470
471 if(active_state().has_value()) {
472 // Here we are testing things that should not change during a renegotiation,
473 // even if the server creates a new session. However they might change
474 // in a resumption scenario.
475
476 if(active_state()->version() != state.server_hello()->legacy_version()) {
477 throw TLS_Exception(Alert::ProtocolVersion, "Server changed version after renegotiation");
478 }
479
480 if(state.server_hello()->supports_extended_master_secret() !=
481 active_state()->supports_extended_master_secret()) {
482 throw TLS_Exception(Alert::HandshakeFailure, "Server changed its mind about extended master secret");
483 }
484 }
485
486 state.discard_resumption_state();
487
488 if(state.client_hello()->legacy_version().is_datagram_protocol() !=
489 state.server_hello()->legacy_version().is_datagram_protocol()) {
490 throw TLS_Exception(Alert::ProtocolVersion, "Server replied with different protocol type than we offered");
491 }
492
493 if(state.version() > state.client_hello()->legacy_version()) {
494 throw TLS_Exception(Alert::HandshakeFailure, "Server replied with later version than client offered");
495 }
496
497 if(state.version().major_version() == 3 && state.version().minor_version() == 0) {
498 throw TLS_Exception(Alert::ProtocolVersion, "Server attempting to negotiate SSLv3 which is not supported");
499 }
500
501 if(!policy().acceptable_protocol_version(state.version())) {
502 throw TLS_Exception(Alert::ProtocolVersion,
503 "Server version " + state.version().to_string() + " is unacceptable by policy");
504 }
505
506 if(state.ciphersuite().is_certificate_required()) {
507 state.set_expected_next(Handshake_Type::Certificate);
508 } else if(state.ciphersuite().kex_method() == Kex_Algo::PSK) {
509 /* PSK is anonymous so no certificate/cert req message is
510 ever sent. The server may or may not send a server kex,
511 depending on if it has an identity hint for us.
512
513 (EC)DHE_PSK always sends a server key exchange for the
514 DH exchange portion, and is covered by block below
515 */
516
517 state.set_expected_next(Handshake_Type::ServerKeyExchange);
518 state.set_expected_next(Handshake_Type::ServerHelloDone);
519 } else {
520 // ECDHE_PSK ServerKeyExchange carries the ECDH parameters and
521 // immediately follows ServerHello.
522 //
523 // Suites using RSA key exchange or signature-authenticated ECDH
524 // were already routed to expect Certificate above.
525 state.set_expected_next(Handshake_Type::ServerKeyExchange);
526 }
527 }
528 } else if(type == Handshake_Type::Certificate) {
529 state.server_certs(std::make_unique<Certificate_12>(contents, policy()));
530
531 const std::vector<X509_Certificate>& server_certs = state.server_certs()->cert_chain();
532
533 if(server_certs.empty()) {
534 throw TLS_Exception(Alert::HandshakeFailure, "Client: No certificates sent by server");
535 }
536
537 /*
538 If the server supports certificate status messages,
539 certificate verification happens after we receive the server hello done,
540 in case an OCSP response was also available
541 */
542
543 const X509_Certificate server_cert = server_certs[0];
544
545 if(active_state().has_value() && !active_state()->peer_certs().empty()) {
546 const X509_Certificate& current_cert = active_state()->peer_certs().at(0);
547
548 if(current_cert != server_cert) {
549 throw TLS_Exception(Alert::BadCertificate, "Server certificate changed during renegotiation");
550 }
551 }
552
553 auto peer_key = server_cert.subject_public_key();
554
555 const std::string expected_key_type =
556 state.ciphersuite().signature_used() ? state.ciphersuite().sig_algo() : "RSA";
557
558 if(peer_key->algo_name() != expected_key_type) {
559 throw TLS_Exception(Alert::IllegalParameter, "Certificate key type did not match ciphersuite");
560 }
561
562 if(!key_usage_matches_ciphersuite(server_cert.constraints(), state.ciphersuite())) {
563 throw TLS_Exception(Alert::BadCertificate, "Certificate usage constraints do not allow this ciphersuite");
564 }
565
566 state.record_server_public_key(std::move(peer_key));
567
568 if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA) {
569 state.set_expected_next(Handshake_Type::ServerKeyExchange);
570 } else {
571 state.set_expected_next(Handshake_Type::CertificateRequest); // optional
572 state.set_expected_next(Handshake_Type::ServerHelloDone);
573 }
574
575 if(state.server_hello()->supports_certificate_status_message()) {
576 state.set_expected_next(Handshake_Type::CertificateStatus); // optional
577 } else {
578 try {
579 auto trusted_CAs = m_creds->trusted_certificate_authorities("tls-client", m_info.hostname());
580
582 server_certs, {}, trusted_CAs, Usage_Type::TLS_SERVER_AUTH, m_info.hostname(), policy());
583 } catch(TLS_Exception&) {
584 throw;
585 } catch(std::exception& e) {
586 throw TLS_Exception(Alert::InternalError, e.what());
587 }
588 }
589 } else if(type == Handshake_Type::CertificateStatus) {
590 state.server_cert_status(std::make_unique<Certificate_Status>(contents, Connection_Side::Server));
591
592 if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA) {
593 state.set_expected_next(Handshake_Type::ServerKeyExchange);
594 } else {
595 state.set_expected_next(Handshake_Type::CertificateRequest); // optional
596 state.set_expected_next(Handshake_Type::ServerHelloDone);
597 }
598 } else if(type == Handshake_Type::ServerKeyExchange) {
599 if(!state.ciphersuite().psk_ciphersuite()) {
600 state.set_expected_next(Handshake_Type::CertificateRequest); // optional
601 }
602 state.set_expected_next(Handshake_Type::ServerHelloDone);
603
604 state.server_kex(std::make_unique<Server_Key_Exchange>(
605 contents, state.ciphersuite().kex_method(), state.ciphersuite().auth_method(), state.version()));
606
607 if(state.ciphersuite().signature_used()) {
608 const Public_Key& server_key = state.server_public_key();
609
610 if(!state.server_kex()->verify(server_key, state, policy())) {
611 throw TLS_Exception(Alert::DecryptError, "Bad signature on server key exchange");
612 }
613 }
614 } else if(type == Handshake_Type::CertificateRequest) {
615 state.set_expected_next(Handshake_Type::ServerHelloDone);
616 state.cert_req(std::make_unique<Certificate_Request_12>(contents));
617 } else if(type == Handshake_Type::ServerHelloDone) {
618 state.server_hello_done(std::make_unique<Server_Hello_Done>(contents));
619
620 if(state.handshake_io().have_more_data()) {
621 throw TLS_Exception(Alert::UnexpectedMessage, "Have data remaining in buffer after ServerHelloDone");
622 }
623
624 if(state.server_certs() != nullptr && state.server_hello()->supports_certificate_status_message()) {
625 try {
626 auto trusted_CAs = m_creds->trusted_certificate_authorities("tls-client", m_info.hostname());
627
628 std::vector<std::optional<OCSP::Response>> ocsp;
629 if(state.server_cert_status() != nullptr) {
630 ocsp.emplace_back(callbacks().tls_parse_ocsp_response(state.server_cert_status()->response()));
631 }
632
633 callbacks().tls_verify_cert_chain(state.server_certs()->cert_chain(),
634 ocsp,
635 trusted_CAs,
637 m_info.hostname(),
638 policy());
639 } catch(TLS_Exception&) {
640 throw;
641 } catch(std::exception& e) {
642 throw TLS_Exception(Alert::InternalError, e.what());
643 }
644 }
645
646 if(state.received_handshake_msg(Handshake_Type::CertificateRequest)) {
647 const auto& types = state.cert_req()->acceptable_cert_types();
648
649 const std::vector<X509_Certificate> client_certs =
650 m_creds->find_cert_chain(types, {}, state.cert_req()->acceptable_CAs(), "tls-client", m_info.hostname());
651
652 state.client_certs(std::make_unique<Certificate_12>(state.handshake_io(), state.hash(), client_certs));
653 }
654
655 state.client_kex(std::make_unique<Client_Key_Exchange>(
656 state.handshake_io(), state, policy(), *m_creds, state.maybe_server_public_key(), m_info.hostname(), rng()));
657
658 state.compute_session_keys();
659 if(policy().allow_ssl_key_log_file()) {
660 // draft-thomson-tls-keylogfile-00 Section 3.2
661 // An implementation of TLS 1.2 (and also earlier versions) use
662 // the label "CLIENT_RANDOM" to identify the "master" secret for
663 // the connection.
665 "CLIENT_RANDOM", state.client_hello()->random(), state.session_keys().master_secret());
666 }
667
668 if(state.received_handshake_msg(Handshake_Type::CertificateRequest) && !state.client_certs()->empty()) {
669 auto private_key =
670 m_creds->private_key_for(state.client_certs()->cert_chain()[0], "tls-client", m_info.hostname());
671
672 if(!private_key) {
673 throw TLS_Exception(Alert::InternalError, "Failed to get private key for signing");
674 }
675
676 state.client_verify(
677 std::make_unique<Certificate_Verify_12>(state.handshake_io(), state, policy(), rng(), private_key.get()));
678 }
679
680 state.handshake_io().send(Change_Cipher_Spec());
681
683
684 state.client_finished(std::make_unique<Finished_12>(state.handshake_io(), state, Connection_Side::Client));
685
686 if(state.server_hello()->supports_session_ticket()) {
687 state.set_expected_next(Handshake_Type::NewSessionTicket);
688 } else {
689 state.set_expected_next(Handshake_Type::HandshakeCCS);
690 }
691 } else if(type == Handshake_Type::NewSessionTicket) {
692 state.new_session_ticket(std::make_unique<New_Session_Ticket_12>(contents));
693
694 state.set_expected_next(Handshake_Type::HandshakeCCS);
695 } else if(type == Handshake_Type::HandshakeCCS) {
696 state.set_expected_next(Handshake_Type::Finished);
697
699 } else if(type == Handshake_Type::Finished) {
700 if(state.handshake_io().have_more_data()) {
701 throw TLS_Exception(Alert::UnexpectedMessage, "Have data remaining in buffer after Finished");
702 }
703
704 state.server_finished(std::make_unique<Finished_12>(contents));
705
706 if(!state.server_finished()->verify(state, Connection_Side::Server)) {
707 throw TLS_Exception(Alert::DecryptError, "Finished message didn't verify");
708 }
709
710 state.hash().update(state.handshake_io().format(contents, type));
711
712 if(state.client_finished() == nullptr) {
713 // session resume case
714 state.handshake_io().send(Change_Cipher_Spec());
716 state.client_finished(std::make_unique<Finished_12>(state.handshake_io(), state, Connection_Side::Client));
717 }
718
719 // Session Tickets (as defined in RFC 5077) contain a lifetime_hint,
720 // sessions identified via a Session_ID do not.
721 const std::chrono::seconds session_lifetime_hint = [&] {
722 if(state.new_session_ticket() != nullptr) {
723 return std::chrono::seconds(state.new_session_ticket()->ticket_lifetime_hint());
724 } else {
725 return std::chrono::seconds::max();
726 }
727 }();
728
729 Session session_info(state.session_keys().master_secret(),
730 state.server_hello()->legacy_version(),
731 state.server_hello()->ciphersuite(),
733 state.server_hello()->supports_extended_master_secret(),
734 state.server_hello()->supports_encrypt_then_mac(),
735 state.peer_cert_chain(),
736 m_info,
737 state.server_hello()->srtp_profile(),
738 callbacks().tls_current_timestamp(),
739 session_lifetime_hint);
740
741 // RFC 5077 3.4
742 // If the client receives a session ticket from the server, then it
743 // discards any Session ID that was sent in the ServerHello.
744 const auto handle = [&]() -> std::optional<Session_Handle> {
745 /*
746 On successful resumption an empty (or absent) NewSessionTicket means "keep using
747 the old ticket" so we inherit it from the ClientHello. On a fresh negotiation
748 an empty NewSessionTicket means "no ticket for this session", so inheriting the
749 ClientHello's old ticket would store the new master secret under a ticket the
750 server has discarded.
751 */
752 if(const auto* nst = state.new_session_ticket(); nst != nullptr && !nst->ticket().empty()) {
753 return Session_Handle(nst->ticket());
754 }
755 if(state.is_a_resumption() && !state.client_hello()->session_ticket().empty()) {
756 return Session_Handle(state.client_hello()->session_ticket());
757 }
758 if(const auto& session_id = state.server_hello()->session_id(); !session_id.empty()) {
759 return Session_Handle(session_id);
760 }
761 return std::nullopt;
762 }();
763
764 // Give the application a chance for a final veto before fully
765 // establishing the connection.
767 Session_Summary summary(session_info, state.is_a_resumption(), state.psk_identity());
768 summary.set_session_id(state.server_hello()->session_id());
769 if(const auto* nst = state.new_session_ticket()) {
770 summary.set_session_ticket(nst->ticket());
771 }
772 return summary;
773 }());
774
775 if(handle.has_value()) {
776 const bool should_save = callbacks().tls_should_persist_resumption_information(session_info);
777
778 // RFC 5077 3.3
779 // If the server successfully verifies the client's ticket, then it
780 // MAY renew the ticket by including a NewSessionTicket handshake
781 // message after the ServerHello in the abbreviated handshake. The
782 // client should start using the new ticket as soon as possible
783 // after it verifies the server's Finished message for new
784 // connections.
785 if(state.is_a_resumption() && !state.client_hello()->session_ticket().empty() && handle->is_ticket() &&
786 should_save) {
787 // renew the session ticket by removing the one we used to establish
788 // this connection and replace it with the one we just received
789 session_manager().remove(Session_Handle(state.client_hello()->session_ticket()));
790 session_manager().store(session_info, handle.value());
791 }
792
793 if(!state.is_a_resumption()) {
794 if(should_save) {
795 session_manager().store(session_info, handle.value());
796 } else {
797 session_manager().remove(handle.value());
798 }
799 }
800 }
801
803
805 } else {
806 throw Unexpected_Message("Unknown handshake message received");
807 }
808}
809
810} // namespace Botan::TLS
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
virtual void tls_examine_extensions(const Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
virtual void tls_session_established(const Session_Summary &session)
virtual bool tls_should_persist_resumption_information(const Session &session)
virtual void tls_verify_cert_chain(const std::vector< X509_Certificate > &cert_chain, const std::vector< std::optional< OCSP::Response > > &ocsp_responses, const std::vector< Certificate_Store * > &trusted_roots, Usage_Type usage, std::string_view hostname, const TLS::Policy &policy)
virtual void tls_ssl_key_log_data(std::string_view label, std::span< const uint8_t > client_random, std::span< const uint8_t > secret) const
RandomNumberGenerator & rng()
void change_cipher_spec_reader(Connection_Side side)
Handshake_State & create_handshake_state(Protocol_Version version, bool epoch0_restart=false)
void secure_renegotiation_check(const Client_Hello_12 *client_hello)
Session_Manager & session_manager()
const Policy & policy() const
void note_resumption_handle(std::optional< Session_Handle > handle)
void change_cipher_spec_writer(Connection_Side side)
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const
Channel_Impl_12(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< RandomNumberGenerator > &rng, const std::shared_ptr< const Policy > &policy, bool is_server, bool is_datagram, size_t io_buf_sz=TLS::Channel::IO_BUF_DEFAULT_SIZE)
const std::optional< Active_Connection_State_12 > & active_state() const
bool secure_renegotiation_supported() const override
void send_warning_alert(Alert::Type type)
static bool is_scsv(uint16_t suite)
static std::optional< Ciphersuite > by_id(uint16_t suite)
Client_Impl_12(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &creds, const std::shared_ptr< const Policy > &policy, const std::shared_ptr< RandomNumberGenerator > &rng, Server_Information server_info=Server_Information(), bool datagram=false, const std::vector< std::string > &next_protocols={}, size_t reserved_io_buffer_size=TLS::Channel::IO_BUF_DEFAULT_SIZE)
void client_hello(std::unique_ptr< Client_Hello_12 > client_hello)
void set_expected_next(Handshake_Type msg_type)
virtual std::optional< size_t > dtls_maximum_hello_verify_requests() const
virtual bool only_resume_with_exact_version() const
virtual bool acceptable_protocol_version(Protocol_Version version) const
virtual size_t remove(const Session_Handle &handle)=0
virtual void store(const Session &session, const Session_Handle &handle)=0
Save a Session under a Session_Handle (TLS Client).
bool value_exists(const std::vector< T > &vec, const V &val)
Definition stl_util.h:44
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128