10#include <botan/tls_client.h>
11#include <botan/tls_messages.h>
12#include <botan/ocsp.h>
13#include <botan/internal/tls_handshake_state.h>
14#include <botan/internal/stl_util.h>
15#include <botan/internal/tls_client_impl_12.h>
24class Client_Handshake_State_12
final :
public Handshake_State
27 Client_Handshake_State_12(std::unique_ptr<Handshake_IO> io, Callbacks& cb) :
28 Handshake_State(
std::move(io), cb),
32 const Public_Key& get_server_public_key()
const
34 BOTAN_ASSERT(server_public_key,
"Server sent us a certificate");
40 bool is_a_renegotiation()
const {
return m_is_reneg; }
42 const secure_vector<uint8_t>& resume_master_secret()
const
48 const std::vector<X509_Certificate>& resume_peer_certs()
const
65 std::shared_ptr<Session_Manager> session_manager,
66 std::shared_ptr<Credentials_Manager> creds,
67 std::shared_ptr<const Policy> policy,
68 std::shared_ptr<RandomNumberGenerator> rng,
71 const std::vector<std::string>& next_protocols,
73 Channel_Impl_12(callbacks, session_manager, rng, policy, false, datagram, io_buf_sz),
78 const auto version = datagram ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
80 send_client_hello(state,
false, version, std::nullopt , next_protocols);
85 downgrade_info.session_manager,
87 downgrade_info.policy,
90 downgrade_info.io_buffer_size),
91 m_creds(downgrade_info.creds),
92 m_info(downgrade_info.server_info)
114 downgrade_info.
tls12_session->session.version().is_pre_tls_13());
119std::unique_ptr<Handshake_State> Client_Impl_12::new_handshake_state(std::unique_ptr<Handshake_IO> io)
121 return std::make_unique<Client_Handshake_State_12>(std::move(io),
callbacks());
124std::vector<X509_Certificate>
125Client_Impl_12::get_peer_cert_chain(
const Handshake_State& state)
const
127 const Client_Handshake_State_12& cstate =
dynamic_cast<const Client_Handshake_State_12&
>(state);
129 if(cstate.is_a_resumption())
130 return cstate.resume_peer_certs();
132 if(state.server_certs())
133 return state.server_certs()->cert_chain();
134 return std::vector<X509_Certificate>();
140void Client_Impl_12::initiate_handshake(Handshake_State& state,
141 bool force_full_renegotiation)
144 const auto version = state.version().is_datagram_protocol()
145 ? Protocol_Version::DTLS_V12
146 : Protocol_Version::TLS_V12;
147 send_client_hello(state, force_full_renegotiation, version);
150void Client_Impl_12::send_client_hello(Handshake_State& state_base,
151 bool force_full_renegotiation,
152 Protocol_Version version,
153 std::optional<Session_with_Handle> session_and_handle,
154 const std::vector<std::string>& next_protocols)
156 Client_Handshake_State_12& state =
dynamic_cast<Client_Handshake_State_12&
>(state_base);
158 if(state.version().is_datagram_protocol())
162 if(!force_full_renegotiation)
165 if(!session_and_handle.has_value() && !m_info.
empty())
169 session_and_handle = std::move(sessions.front());
173 if(session_and_handle.has_value())
179 auto& session_info = session_and_handle->session;
180 const bool exact_version = session_info.version() == version;
181 const bool ok_version =
182 (session_info.version().is_datagram_protocol() == version.is_datagram_protocol()) &&
187 if(
policy().acceptable_ciphersuite(session_info.ciphersuite()) && session_version_ok)
190 new Client_Hello_12(state.handshake_io(),
196 session_and_handle.value(),
199 state.resumed_session = std::move(session_info);
204 if(!state.client_hello())
206 Client_Hello_12::Settings client_settings(version, m_info.
hostname());
207 state.client_hello(
new Client_Hello_12(
208 state.handshake_io(),
223bool key_usage_matches_ciphersuite(Key_Constraints usage,
224 const Ciphersuite& suite)
246void Client_Impl_12::process_handshake_msg(
const Handshake_State* active_state,
247 Handshake_State& state_base,
249 const std::vector<uint8_t>& contents,
254 Client_Handshake_State_12& state =
dynamic_cast<Client_Handshake_State_12&
>(state_base);
258 Hello_Request hello_request(contents);
260 if(state.client_hello())
262 throw TLS_Exception(Alert::HandshakeFailure,
"Cannot renegotiate during a handshake");
265 if(
policy().allow_server_initiated_renegotiation())
269 state.m_is_reneg =
true;
270 initiate_handshake(state,
true );
274 throw TLS_Exception(Alert::HandshakeFailure,
"Client policy prohibits insecure renegotiation");
279 if(
policy().abort_connection_on_undesired_renegotiation())
281 throw TLS_Exception(Alert::NoRenegotiation,
"Client policy prohibits renegotiation");
293 state.confirm_transition_to(type);
299 state.hash().update(state.handshake_io().format(contents, type));
307 Hello_Verify_Request hello_verify_request(contents);
308 state.hello_verify_request(hello_verify_request);
312 state.server_hello(
new Server_Hello_12(contents));
314 if(!state.server_hello()->legacy_version().valid())
316 throw TLS_Exception(Alert::ProtocolVersion,
317 "Server replied with an invalid version");
320 if(!state.client_hello()->offered_suite(state.server_hello()->ciphersuite()))
322 throw TLS_Exception(Alert::HandshakeFailure,
323 "Server replied with ciphersuite we didn't send");
327 !suite || !suite->usable_in_version(state.server_hello()->legacy_version()))
329 throw TLS_Exception(Alert::HandshakeFailure,
330 "Server replied using a ciphersuite not allowed in version it offered");
335 throw TLS_Exception(Alert::HandshakeFailure,
336 "Server replied with a signaling ciphersuite");
339 if(state.server_hello()->compression_method() != 0)
341 throw TLS_Exception(Alert::IllegalParameter,
342 "Server replied with non-null compression method");
345 if(state.client_hello()->legacy_version() > state.server_hello()->legacy_version())
356 if(
auto requested = state.server_hello()->random_signals_downgrade();
357 requested.has_value() && requested.value() <= Protocol_Version::TLS_V11)
358 throw TLS_Exception(Alert::IllegalParameter,
"Downgrade attack detected");
361 auto client_extn = state.client_hello()->extension_types();
362 auto server_extn = state.server_hello()->extension_types();
364 std::vector<Extension_Code> diff;
366 std::set_difference(server_extn.begin(), server_extn.end(),
367 client_extn.begin(), client_extn.end(),
368 std::back_inserter(diff));
374 std::ostringstream msg;
375 msg <<
"Server replied with unsupported extensions:";
377 msg <<
" " <<
static_cast<int>(d);
378 throw TLS_Exception(Alert::UnsupportedExtension, msg.str());
381 if(uint16_t srtp = state.server_hello()->srtp_profile())
383 if(!
value_exists(state.client_hello()->srtp_profiles(), srtp))
384 throw TLS_Exception(Alert::HandshakeFailure,
385 "Server replied with DTLS-SRTP alg we did not send");
390 state.set_version(state.server_hello()->legacy_version());
391 m_application_protocol = state.server_hello()->next_protocol();
395 const bool server_returned_same_session_id =
396 !state.server_hello()->session_id().empty() &&
397 (state.server_hello()->session_id() == state.client_hello()->session_id());
399 if(server_returned_same_session_id)
408 if(state.server_hello()->legacy_version() != state.client_hello()->legacy_version())
409 throw TLS_Exception(Alert::HandshakeFailure,
410 "Server resumed session but with wrong version");
412 if(state.server_hello()->supports_extended_master_secret() &&
413 !state.resumed_session->supports_extended_master_secret())
415 throw TLS_Exception(Alert::HandshakeFailure,
416 "Server resumed session but added extended master secret");
419 if(!state.server_hello()->supports_extended_master_secret() &&
420 state.resumed_session->supports_extended_master_secret())
422 throw TLS_Exception(Alert::HandshakeFailure,
423 "Server resumed session and removed extended master secret");
426 state.compute_session_keys(state.resume_master_secret());
428 if(state.server_hello()->supports_session_ticket())
447 if(active_state->version() != state.server_hello()->legacy_version())
448 throw TLS_Exception(Alert::ProtocolVersion,
449 "Server changed version after renegotiation");
451 if(state.server_hello()->supports_extended_master_secret() !=
452 active_state->server_hello()->supports_extended_master_secret())
454 throw TLS_Exception(Alert::HandshakeFailure,
455 "Server changed its mind about extended master secret");
459 state.resumed_session.reset();
461 if(state.client_hello()->legacy_version().is_datagram_protocol() !=
462 state.server_hello()->legacy_version().is_datagram_protocol())
464 throw TLS_Exception(Alert::ProtocolVersion,
465 "Server replied with different protocol type than we offered");
468 if(state.version() > state.client_hello()->legacy_version())
470 throw TLS_Exception(Alert::HandshakeFailure,
471 "Server replied with later version than client offered");
474 if(state.version().major_version() == 3 && state.version().minor_version() == 0)
476 throw TLS_Exception(Alert::ProtocolVersion,
477 "Server attempting to negotiate SSLv3 which is not supported");
480 if(!
policy().acceptable_protocol_version(state.version()))
482 throw TLS_Exception(Alert::ProtocolVersion,
483 "Server version " + state.version().to_string() +
484 " is unacceptable by policy");
487 if(state.ciphersuite().signature_used() || state.ciphersuite().kex_method() ==
Kex_Algo::STATIC_RSA)
517 state.server_certs(
new Certificate_12(contents,
policy()));
519 const std::vector<X509_Certificate>& server_certs =
520 state.server_certs()->cert_chain();
522 if(server_certs.empty())
523 throw TLS_Exception(Alert::HandshakeFailure,
524 "Client: No certificates sent by server");
532 X509_Certificate server_cert = server_certs[0];
534 if(active_state && active_state->server_certs())
536 X509_Certificate current_cert = active_state->server_certs()->cert_chain().at(0);
538 if(current_cert != server_cert)
539 throw TLS_Exception(Alert::BadCertificate,
"Server certificate changed during renegotiation");
542 auto peer_key = server_cert.subject_public_key();
544 const std::string expected_key_type =
545 state.ciphersuite().signature_used() ? state.ciphersuite().sig_algo() :
"RSA";
547 if(peer_key->algo_name() != expected_key_type)
548 throw TLS_Exception(Alert::IllegalParameter,
549 "Certificate key type did not match ciphersuite");
551 if(!key_usage_matches_ciphersuite(server_cert.constraints(), state.ciphersuite()))
552 throw TLS_Exception(Alert::BadCertificate,
553 "Certificate usage constraints do not allow this ciphersuite");
555 state.server_public_key.reset(peer_key.release());
567 if(state.server_hello()->supports_certificate_status_message())
575 auto trusted_CAs = m_creds->trusted_certificate_authorities(
"tls-client", m_info.
hostname());
584 catch(TLS_Exception&)
588 catch(std::exception& e)
590 throw TLS_Exception(Alert::InternalError, e.what());
610 if(state.ciphersuite().psk_ciphersuite() ==
false)
615 new Server_Key_Exchange(contents,
616 state.ciphersuite().kex_method(),
617 state.ciphersuite().auth_method(),
621 if(state.ciphersuite().signature_used())
623 const Public_Key& server_key = state.get_server_public_key();
625 if(!state.server_kex()->verify(server_key, state,
policy()))
627 throw TLS_Exception(Alert::DecryptError,
628 "Bad signature on server key exchange");
635 state.cert_req(
new Certificate_Request_12(contents));
639 state.server_hello_done(
new Server_Hello_Done(contents));
641 if(state.handshake_io().have_more_data())
642 throw TLS_Exception(Alert::UnexpectedMessage,
643 "Have data remaining in buffer after ServerHelloDone");
646 if(state.server_certs() !=
nullptr &&
647 state.server_hello()->supports_certificate_status_message())
651 auto trusted_CAs = m_creds->trusted_certificate_authorities(
"tls-client", m_info.
hostname());
653 std::vector<std::optional<OCSP::Response>> ocsp;
654 if(state.server_cert_status() !=
nullptr)
656 ocsp.emplace_back(
callbacks().tls_parse_ocsp_response(state.server_cert_status()->response()));
666 catch(TLS_Exception&)
670 catch(std::exception& e)
672 throw TLS_Exception(Alert::InternalError, e.what());
678 const auto& types = state.cert_req()->acceptable_cert_types();
680 std::vector<X509_Certificate> client_certs =
681 m_creds->find_cert_chain(types,
683 state.cert_req()->acceptable_CAs(),
687 state.client_certs(
new Certificate_12(state.handshake_io(),
693 new Client_Key_Exchange(state.handshake_io(),
697 state.server_public_key.get(),
702 state.compute_session_keys();
705 !state.client_certs()->empty())
708 m_creds->private_key_for(state.client_certs()->cert_chain()[0],
713 throw TLS_Exception(Alert::InternalError,
"Failed to get private key for signing");
716 new Certificate_Verify_12(state.handshake_io(),
724 state.handshake_io().send(Change_Cipher_Spec());
730 if(state.server_hello()->supports_session_ticket())
737 state.new_session_ticket(
new New_Session_Ticket_12(contents));
749 if(state.handshake_io().have_more_data())
750 throw TLS_Exception(Alert::UnexpectedMessage,
751 "Have data remaining in buffer after Finished");
753 state.server_finished(
new Finished_12(contents));
756 throw TLS_Exception(Alert::DecryptError,
757 "Finished message didn't verify");
759 state.hash().update(state.handshake_io().format(contents, type));
761 if(!state.client_finished())
764 state.handshake_io().send(Change_Cipher_Spec());
769 Session session_info(
770 state.session_keys().master_secret(),
771 state.server_hello()->legacy_version(),
772 state.server_hello()->ciphersuite(),
774 state.server_hello()->supports_extended_master_secret(),
775 state.server_hello()->supports_encrypt_then_mac(),
776 get_peer_cert_chain(state),
778 state.server_hello()->srtp_profile(),
783 ((state.new_session_ticket())
784 ? state.new_session_ticket()->ticket_lifetime_hint()
785 : std::chrono::seconds::max())
791 const auto handle = [&]() -> std::optional<Session_Handle>
793 if(
const auto& session_ticket = state.session_ticket(); !session_ticket.empty())
794 {
return session_ticket; }
795 else if(
const auto& session_id = state.server_hello()->session_id(); !session_id.empty())
796 {
return session_id; }
798 {
return std::nullopt; }
805 Session_Summary summary(session_info, state.is_a_resumption());
806 summary.set_session_id(state.server_hello()->session_id());
807 if(
auto nst = state.new_session_ticket())
809 summary.set_session_ticket(nst->ticket());
814 if(handle.has_value())
816 const bool should_save =
826 if(state.is_a_resumption() &&
827 !state.client_hello()->session_ticket().empty() &&
828 handle->is_ticket() &&
837 if(!state.is_a_resumption())
849 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_session_established(const Session_Summary &session)
virtual void tls_examine_extensions(const Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
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)
RandomNumberGenerator & rng()
void change_cipher_spec_reader(Connection_Side side)
Handshake_State & create_handshake_state(Protocol_Version version)
Callbacks & callbacks() const
void secure_renegotiation_check(const Client_Hello_12 *client_hello)
Session_Manager & session_manager()
const Policy & policy() const
void change_cipher_spec_writer(Connection_Side side)
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() 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(std::shared_ptr< Callbacks > callbacks, std::shared_ptr< Session_Manager > session_manager, std::shared_ptr< Credentials_Manager > creds, std::shared_ptr< const Policy > policy, 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 update(const uint8_t in[], size_t length)
void set_expected_next(Handshake_Type msg_type)
void client_hello(Client_Hello_12 *client_hello)
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)
virtual std::vector< Session_with_Handle > find(const Server_Information &info, Callbacks &callbacks, const Policy &policy)
Find all sessions that match a given server info.
int(* final)(unsigned char *, CTX *)
bool value_exists(const std::vector< T > &vec, const OT &val)
std::unique_ptr< Public_Key > server_public_key
std::optional< Session > resumed_session