10#include <botan/internal/tls_client_impl_12.h>
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>
29 Client_Handshake_State_12(std::unique_ptr<Handshake_IO> io, Callbacks& cb) :
30 Handshake_State(std::move(io), cb), m_is_reneg(false) {}
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;
37 const Public_Key* maybe_server_public_key()
const {
return m_server_public_key.get(); }
39 void record_server_public_key(std::unique_ptr<Public_Key> spk) {
41 m_server_public_key = std::move(spk);
44 bool is_a_resumption()
const {
return m_resumed_session.has_value(); }
46 void discard_resumption_state() { m_resumed_session.reset(); }
48 void record_resumption_info(std::optional<Session> session_info) {
50 m_resumed_session = std::move(session_info);
53 bool is_a_renegotiation()
const {
return m_is_reneg; }
55 void mark_as_renegotiation() { m_is_reneg =
true; }
57 size_t note_hello_verify_request() {
return ++m_hello_verify_requests; }
61 return m_resumed_session->master_secret();
64 const std::vector<X509_Certificate>& resume_peer_certs()
const {
66 return m_resumed_session->peer_certs();
69 bool resumed_session_supports_extended_master_secret()
const {
71 return m_resumed_session->supports_extended_master_secret();
74 uint16_t resumed_session_ciphersuite_code()
const {
76 return m_resumed_session->ciphersuite_code();
79 std::vector<X509_Certificate> peer_cert_chain()
const override {
80 if(is_a_resumption()) {
81 return resume_peer_certs();
83 if(server_certs() !=
nullptr) {
84 return server_certs()->cert_chain();
90 std::unique_ptr<Public_Key> m_server_public_key;
93 std::optional<Session> m_resumed_session;
94 bool m_is_reneg =
false;
95 size_t m_hello_verify_requests = 0;
105 const std::shared_ptr<Credentials_Manager>& creds,
106 const std::shared_ptr<const Policy>&
policy,
107 const std::shared_ptr<RandomNumberGenerator>&
rng,
110 const std::vector<std::string>& next_protocols,
114 m_info(std::move(info)) {
116 const auto version = datagram ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
118 send_client_hello(state,
false, version, std::nullopt , next_protocols);
121#if defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
125 downgrade_info.session_manager,
127 downgrade_info.policy,
130 downgrade_info.io_buffer_size),
131 m_creds(downgrade_info.creds),
132 m_info(downgrade_info.server_info) {
135 if(downgrade_info.client_hello.has_value()) {
140 std::exchange(downgrade_info.client_hello, {}).value(), state.
handshake_io(), state.
hash()));
148 downgrade_info.tls12_session->session.version().is_pre_tls_13());
149 send_client_hello(state,
151 downgrade_info.tls12_session->session.version(),
152 downgrade_info.tls12_session,
153 downgrade_info.next_protocols);
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());
166void Client_Impl_12::initiate_handshake(
Handshake_State& state,
bool force_full_renegotiation) {
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);
173 bool force_full_renegotiation,
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);
179 if(state.version().is_datagram_protocol()) {
184 if(!force_full_renegotiation) {
186 if(!session_and_handle.has_value() && !m_info.empty()) {
188 session_and_handle = std::move(sessions.front());
192 if(session_and_handle.has_value()) {
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()) &&
204 if(
policy().acceptable_ciphersuite(session_info.ciphersuite()) && session_version_ok) {
205 state.client_hello(std::make_unique<Client_Hello_12>(state.handshake_io(),
211 session_and_handle.value(),
214 state.record_resumption_info(std::move(session_info));
219 if(state.client_hello() ==
nullptr) {
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(),
237bool key_usage_matches_ciphersuite(Key_Constraints usage,
const Ciphersuite& suite) {
256 const std::vector<uint8_t>& contents,
257 bool epoch0_restart) {
260 Client_Handshake_State_12& state =
dynamic_cast<Client_Handshake_State_12&
>(state_base);
263 const Hello_Request hello_request(contents);
268 if(state.client_hello() !=
nullptr) {
272 if(
policy().allow_server_initiated_renegotiation()) {
274 state.mark_as_renegotiation();
275 initiate_handshake(state,
true );
277 throw TLS_Exception(Alert::HandshakeFailure,
"Client policy prohibits insecure renegotiation");
280 if(
policy().abort_connection_on_undesired_renegotiation()) {
281 throw TLS_Exception(Alert::NoRenegotiation,
"Client policy prohibits renegotiation");
291 state.confirm_transition_to(type);
295 state.hash().update(state.handshake_io().format(contents, type));
308 const size_t hello_verify_requests = state.note_hello_verify_request();
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");
318 const Hello_Verify_Request hello_verify_request(contents);
319 state.hello_verify_request(hello_verify_request);
321 state.server_hello(std::make_unique<Server_Hello_12>(contents));
323 if(!state.server_hello()->legacy_version().valid()) {
324 throw TLS_Exception(Alert::ProtocolVersion,
"Server replied with an invalid version");
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");
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");
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");
348 throw TLS_Exception(Alert::HandshakeFailure,
"Server replied with a signaling ciphersuite");
351 if(state.server_hello()->compression_method() != 0) {
352 throw TLS_Exception(Alert::IllegalParameter,
"Server replied with non-null compression method");
355 if(state.client_hello()->legacy_version() > state.server_hello()->legacy_version()) {
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");
371 auto client_extn = state.client_hello()->extension_types();
372 auto server_extn = state.server_hello()->extension_types();
374 std::vector<Extension_Code> diff;
377 server_extn.begin(), server_extn.end(), client_extn.begin(), client_extn.end(), std::back_inserter(diff));
382 std::ostringstream msg;
383 msg <<
"Server replied with unsupported extensions:";
384 for(
auto&& d : diff) {
385 msg <<
" " <<
static_cast<int>(d);
387 throw TLS_Exception(Alert::UnsupportedExtension, msg.str());
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");
399 state.set_version(state.server_hello()->legacy_version());
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>();
406 const auto& offered = client_alpn->protocols();
408 throw TLS_Exception(Alert::IllegalParameter,
"Server selected an ALPN protocol not offered by the client");
411 m_application_protocol = state.server_hello()->next_protocol();
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");
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());
425 if(server_returned_same_session_id) {
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");
439 if(state.server_hello()->ciphersuite() != state.resumed_session_ciphersuite_code()) {
440 throw TLS_Exception(Alert::HandshakeFailure,
"Server resumed session with a different ciphersuite");
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");
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");
453 state.compute_session_keys(state.resume_master_secret());
454 if(
policy().allow_ssl_key_log_file()) {
460 "CLIENT_RANDOM", state.client_hello()->random(), state.session_keys().master_secret());
463 if(state.server_hello()->supports_session_ticket()) {
476 if(
active_state()->version() != state.server_hello()->legacy_version()) {
477 throw TLS_Exception(Alert::ProtocolVersion,
"Server changed version after renegotiation");
480 if(state.server_hello()->supports_extended_master_secret() !=
482 throw TLS_Exception(Alert::HandshakeFailure,
"Server changed its mind about extended master secret");
486 state.discard_resumption_state();
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");
493 if(state.version() > state.client_hello()->legacy_version()) {
494 throw TLS_Exception(Alert::HandshakeFailure,
"Server replied with later version than client offered");
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");
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");
506 if(state.ciphersuite().is_certificate_required()) {
508 }
else if(state.ciphersuite().kex_method() ==
Kex_Algo::PSK) {
529 state.server_certs(std::make_unique<Certificate_12>(contents,
policy()));
531 const std::vector<X509_Certificate>& server_certs = state.server_certs()->cert_chain();
533 if(server_certs.empty()) {
534 throw TLS_Exception(Alert::HandshakeFailure,
"Client: No certificates sent by server");
543 const X509_Certificate server_cert = server_certs[0];
546 const X509_Certificate& current_cert =
active_state()->peer_certs().at(0);
548 if(current_cert != server_cert) {
549 throw TLS_Exception(Alert::BadCertificate,
"Server certificate changed during renegotiation");
553 auto peer_key = server_cert.subject_public_key();
555 const std::string expected_key_type =
556 state.ciphersuite().signature_used() ? state.ciphersuite().sig_algo() :
"RSA";
558 if(peer_key->algo_name() != expected_key_type) {
559 throw TLS_Exception(Alert::IllegalParameter,
"Certificate key type did not match ciphersuite");
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");
566 state.record_server_public_key(std::move(peer_key));
575 if(state.server_hello()->supports_certificate_status_message()) {
579 auto trusted_CAs = m_creds->trusted_certificate_authorities(
"tls-client", m_info.hostname());
583 }
catch(TLS_Exception&) {
585 }
catch(std::exception& e) {
586 throw TLS_Exception(Alert::InternalError, e.what());
599 if(!state.ciphersuite().psk_ciphersuite()) {
604 state.server_kex(std::make_unique<Server_Key_Exchange>(
605 contents, state.ciphersuite().kex_method(), state.ciphersuite().auth_method(), state.version()));
607 if(state.ciphersuite().signature_used()) {
608 const Public_Key& server_key = state.server_public_key();
610 if(!state.server_kex()->verify(server_key, state,
policy())) {
611 throw TLS_Exception(Alert::DecryptError,
"Bad signature on server key exchange");
616 state.cert_req(std::make_unique<Certificate_Request_12>(contents));
618 state.server_hello_done(std::make_unique<Server_Hello_Done>(contents));
620 if(state.handshake_io().have_more_data()) {
621 throw TLS_Exception(Alert::UnexpectedMessage,
"Have data remaining in buffer after ServerHelloDone");
624 if(state.server_certs() !=
nullptr && state.server_hello()->supports_certificate_status_message()) {
626 auto trusted_CAs = m_creds->trusted_certificate_authorities(
"tls-client", m_info.hostname());
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()));
639 }
catch(TLS_Exception&) {
641 }
catch(std::exception& e) {
642 throw TLS_Exception(Alert::InternalError, e.what());
647 const auto& types = state.cert_req()->acceptable_cert_types();
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());
652 state.client_certs(std::make_unique<Certificate_12>(state.handshake_io(), state.hash(), client_certs));
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()));
658 state.compute_session_keys();
659 if(
policy().allow_ssl_key_log_file()) {
665 "CLIENT_RANDOM", state.client_hello()->random(), state.session_keys().master_secret());
670 m_creds->private_key_for(state.client_certs()->cert_chain()[0],
"tls-client", m_info.hostname());
673 throw TLS_Exception(Alert::InternalError,
"Failed to get private key for signing");
677 std::make_unique<Certificate_Verify_12>(state.handshake_io(), state,
policy(),
rng(), private_key.get()));
680 state.handshake_io().send(Change_Cipher_Spec());
686 if(state.server_hello()->supports_session_ticket()) {
692 state.new_session_ticket(std::make_unique<New_Session_Ticket_12>(contents));
700 if(state.handshake_io().have_more_data()) {
701 throw TLS_Exception(Alert::UnexpectedMessage,
"Have data remaining in buffer after Finished");
704 state.server_finished(std::make_unique<Finished_12>(contents));
707 throw TLS_Exception(Alert::DecryptError,
"Finished message didn't verify");
710 state.hash().update(state.handshake_io().format(contents, type));
712 if(state.client_finished() ==
nullptr) {
714 state.handshake_io().send(Change_Cipher_Spec());
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());
725 return std::chrono::seconds::max();
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(),
737 state.server_hello()->srtp_profile(),
739 session_lifetime_hint);
744 const auto handle = [&]() -> std::optional<Session_Handle> {
752 if(
const auto* nst = state.new_session_ticket(); nst !=
nullptr && !nst->ticket().empty()) {
753 return Session_Handle(nst->ticket());
755 if(state.is_a_resumption() && !state.client_hello()->session_ticket().empty()) {
756 return Session_Handle(state.client_hello()->session_ticket());
758 if(
const auto& session_id = state.server_hello()->session_id(); !session_id.empty()) {
759 return Session_Handle(session_id);
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());
775 if(handle.has_value()) {
785 if(state.is_a_resumption() && !state.client_hello()->session_ticket().empty() && handle->is_ticket() &&
793 if(!state.is_a_resumption()) {
806 throw Unexpected_Message(
"Unknown handshake message received");
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
#define BOTAN_ASSERT(expr, assertion_made)
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)
Callbacks & callbacks() const
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)
Handshake_IO & handshake_io()
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)
std::vector< T, secure_allocator< T > > secure_vector