9#include <botan/internal/tls_handshake_state.h>
12#include <botan/tls_messages.h>
13#include <botan/tls_signature_scheme.h>
14#include <botan/internal/tls_record.h>
26 return "hello_verify_request";
29 return "hello_request";
32 return "client_hello";
35 return "server_hello";
38 return "hello_retry_request";
44 return "certificate_url";
47 return "certificate_status";
50 return "server_key_exchange";
53 return "certificate_request";
56 return "server_hello_done";
59 return "certificate_verify";
62 return "client_key_exchange";
65 return "new_session_ticket";
68 return "change_cipher_spec";
74 return "end_of_early_data";
77 return "encrypted_extensions";
87 "Unknown TLS handshake message type " + std::to_string(
static_cast<size_t>(type)));
96 m_callbacks(cb), m_handshake_io(std::move(io)), m_version(m_handshake_io->initial_record_version()) {}
99 m_callbacks.tls_inspect_handshake_msg(msg);
105 m_client_hello->update_hello_cookie(hello_verify);
114 m_client_hello.reset();
202 if(!m_ciphersuite.has_value()) {
205 return m_ciphersuite.value();
212 return m_client_kex->psk_identity();
224 m_session_keys =
Session_Keys(
this, resume_master_secret,
true);
228 m_transitions.confirm_transition_to(handshake_msg);
232 m_transitions.set_expected_next(handshake_msg);
236 return m_transitions.received_handshake_msg(handshake_msg);
240 return m_handshake_io->get_next_record(m_transitions.change_cipher_spec_expected());
245 const auto& ticket = nst->ticket();
246 if(!ticket.empty()) {
257 if(prf_algo ==
"MD5" || prf_algo ==
"SHA-1") {
266 bool for_client_auth,
267 const Policy& policy)
const {
268 const std::string sig_algo = key.
algo_name();
272 std::vector<Signature_Scheme> requested =
276 if(!scheme.is_available()) {
280 if(scheme.algorithm_name() == sig_algo) {
281 if(std::find(requested.begin(), requested.end(), scheme) != requested.end()) {
282 chosen_scheme = scheme;
291 throw TLS_Exception(Alert::HandshakeFailure,
"Policy refuses to accept signing with any hash supported by peer");
294 if(!chosen_scheme.
format().has_value()) {
295 throw Invalid_Argument(sig_algo +
" is invalid/unknown for TLS signatures");
303bool supported_algos_include(
const std::vector<Signature_Scheme>& schemes,
304 std::string_view key_type,
305 std::string_view hash_type) {
307 if(scheme.is_available() && hash_type == scheme.hash_function_name() && key_type == scheme.algorithm_name()) {
320 const std::vector<Signature_Scheme>& offered_schemes,
321 bool for_client_auth,
322 const Policy& policy)
const {
323 const std::string key_type = key.
algo_name();
326 throw TLS_Exception(Alert::HandshakeFailure,
"Rejecting " + key_type +
" signature");
330 throw TLS_Exception(Alert::IllegalParameter,
"Peer sent unknown signature scheme");
334 throw Decoding_Error(
"Counterparty sent inconsistent key and sig types");
337 if(for_client_auth &&
cert_req() ==
nullptr) {
338 throw TLS_Exception(Alert::HandshakeFailure,
"No CertificateVerify message received");
346 const std::vector<Signature_Scheme> supported_algos =
352 throw TLS_Exception(Alert::IllegalParameter,
"Peer sent unexceptable signature scheme");
355 if(!supported_algos_include(supported_algos, key_type, hash_algo)) {
357 "TLS signature extension did not allow for " + key_type +
"/" + hash_algo +
" signature");
360 if(!scheme.
format().has_value()) {
361 throw Invalid_Argument(key_type +
" is invalid/unknown for TLS signatures");
#define BOTAN_ASSERT_NONNULL(ptr)
virtual std::string algo_name() const =0
static std::unique_ptr< KDF > create_or_throw(std::string_view algo_spec, std::string_view provider="")
const std::vector< Signature_Scheme > & signature_schemes() const
static std::optional< Ciphersuite > by_id(uint16_t suite)
std::string prf_algo() const
Session_Ticket session_ticket() const
std::vector< Signature_Scheme > signature_schemes() const
void update(const uint8_t in[], size_t length)
std::string type_string() const
virtual Handshake_Type type() const =0
std::pair< std::string, Signature_Format > parse_sig_format(const Public_Key &key, Signature_Scheme scheme, const std::vector< Signature_Scheme > &offered_schemes, bool for_client_auth, const Policy &policy) const
void server_finished(std::unique_ptr< Finished_12 > server_finished)
void client_hello(std::unique_ptr< Client_Hello_12 > client_hello)
std::pair< Handshake_Type, std::vector< uint8_t > > get_next_handshake_msg()
const Server_Hello_Done * server_hello_done() const
void hello_verify_request(const Hello_Verify_Request &hello_verify)
void set_expected_next(Handshake_Type msg_type)
void note_message(const Handshake_Message &msg)
const Server_Key_Exchange * server_kex() const
virtual ~Handshake_State()
const Certificate_Status * server_cert_status() const
const Certificate_Verify_12 * server_verify() const
Handshake_State(std::unique_ptr< Handshake_IO > io, Callbacks &callbacks)
Handshake_IO & handshake_io()
void server_verify(std::unique_ptr< Certificate_Verify_12 > server_verify)
void new_session_ticket(std::unique_ptr< New_Session_Ticket_12 > new_session_ticket)
void client_certs(std::unique_ptr< Certificate_12 > client_certs)
void client_kex(std::unique_ptr< Client_Key_Exchange > client_kex)
const Certificate_Verify_12 * client_verify() const
const Finished_12 * server_finished() const
void server_hello_done(std::unique_ptr< Server_Hello_Done > server_hello_done)
const Client_Hello_12 * client_hello() const
const Client_Key_Exchange * client_kex() const
void cert_req(std::unique_ptr< Certificate_Request_12 > cert_req)
void server_cert_status(std::unique_ptr< Certificate_Status > server_cert_status)
void server_hello(std::unique_ptr< Server_Hello_12 > server_hello)
void confirm_transition_to(Handshake_Type msg_type)
void set_version(const Protocol_Version &version)
void client_finished(std::unique_ptr< Finished_12 > client_finished)
std::optional< std::string > psk_identity() const
const Certificate_12 * server_certs() const
const Certificate_12 * client_certs() const
void client_verify(std::unique_ptr< Certificate_Verify_12 > client_verify)
const Finished_12 * client_finished() const
const Certificate_Request_12 * cert_req() const
void compute_session_keys()
const Ciphersuite & ciphersuite() const
Session_Ticket session_ticket() const
void server_kex(std::unique_ptr< Server_Key_Exchange > server_kex)
const Server_Hello_12 * server_hello() const
bool received_handshake_msg(Handshake_Type msg_type) const
void server_certs(std::unique_ptr< Certificate_12 > server_certs)
std::unique_ptr< KDF > protocol_specific_prf() const
const New_Session_Ticket_12 * new_session_ticket() const
std::pair< std::string, Signature_Format > choose_sig_format(const Private_Key &key, Signature_Scheme &scheme, bool for_client_auth, const Policy &policy) const
Protocol_Version version() const
virtual std::vector< Signature_Scheme > allowed_signature_schemes() const
bool allowed_signature_method(std::string_view sig_method) const
bool allowed_signature_hash(std::string_view hash) const
std::string hash_function_name() const noexcept
bool is_compatible_with(const Protocol_Version &protocol_version) const noexcept
std::optional< Signature_Format > format() const noexcept
std::string padding_string() const noexcept
bool is_available() const noexcept
std::string algorithm_name() const noexcept
const char * handshake_type_to_string(Handshake_Type type)
Strong< std::vector< uint8_t >, struct Session_Ticket_ > Session_Ticket
holds a TLS 1.2 session ticket for stateless resumption
std::vector< T, secure_allocator< T > > secure_vector