9#include <botan/tls_messages.h>
11#include <botan/credentials_manager.h>
12#include <botan/pubkey.h>
13#include <botan/tls_extensions.h>
14#include <botan/internal/loadstor.h>
15#include <botan/internal/tls_handshake_io.h>
16#include <botan/internal/tls_handshake_state.h>
17#include <botan/internal/tls_reader.h>
20#include <botan/dl_group.h>
21#include <botan/ecdh.h>
23#if defined(BOTAN_HAS_X25519)
24 #include <botan/x25519.h>
26#if defined(BOTAN_HAS_X448)
27 #include <botan/x448.h>
41 const std::string hostname = state.
client_hello()->sni_hostname();
51 const std::vector<Group_Params> dh_groups = state.
client_hello()->supported_dh_groups();
53 m_shared_group = Group_Params::NONE;
64 if(dh_groups.empty()) {
70 if(m_shared_group.value() == Group_Params::NONE) {
71 throw TLS_Exception(Alert::HandshakeFailure,
"Could not agree on a DH group with the client");
75 BOTAN_ASSERT(m_shared_group.value().is_dh_named_group(),
"DH ciphersuite is using a known finite field group");
88 throw TLS_Exception(Alert::InternalError,
"Application did not provide a Diffie-Hellman key");
95 const std::vector<Group_Params> ec_groups = state.
client_hello()->supported_ecc_curves();
97 if(ec_groups.empty()) {
98 throw Internal_Error(
"Client sent no ECC extension but we negotiated ECDH");
103 if(m_shared_group.value() == Group_Params::NONE) {
104 throw TLS_Exception(Alert::HandshakeFailure,
"No shared ECC group with client");
107 std::vector<uint8_t> ecdh_public_val;
109 if(m_shared_group.value() == Group_Params::X25519 || m_shared_group.value() == Group_Params::X448) {
112 throw TLS_Exception(Alert::InternalError,
"Application did not provide an EC key");
114 ecdh_public_val = m_kex_key->public_value();
119 throw TLS_Exception(Alert::InternalError,
"Application did not provide a EC-Diffie-Hellman key");
128 const uint16_t named_curve_id = m_shared_group.value().wire_code();
129 m_params.push_back(3);
141 std::pair<std::string, Signature_Format> format = state.
choose_sig_format(*signing_key, m_scheme,
false, policy);
143 std::vector<uint8_t> buf = state.
client_hello()->random();
177 for(
size_t i = 0; i != 3; ++i) {
188 m_params.assign(buf.data(), buf.data() + reader.
read_so_far());
192 m_signature = reader.
get_range<uint8_t>(2, 0, 65535);
201std::vector<uint8_t> Server_Key_Exchange::serialize()
const {
202 std::vector<uint8_t> buf =
params();
204 if(!m_signature.empty()) {
221 const Policy& policy)
const {
224 std::pair<std::string, Signature_Format> format =
227 std::vector<uint8_t> buf = state.
client_hello()->random();
232 const bool signature_valid =
235#if defined(BOTAN_UNSAFE_FUZZER_MODE)
239 return signature_valid;
#define BOTAN_ASSERT_NONNULL(ptr)
#define BOTAN_ASSERT(expr, assertion_made)
virtual std::string psk_identity_hint(const std::string &type, const std::string &context)
std::vector< uint8_t > public_value() const override
virtual std::vector< uint8_t > tls_sign_message(const Private_Key &key, RandomNumberGenerator &rng, std::string_view padding, Signature_Format format, const std::vector< uint8_t > &msg)
virtual std::unique_ptr< PK_Key_Agreement_Key > tls_generate_ephemeral_key(const std::variant< TLS::Group_Params, DL_Group > &group, RandomNumberGenerator &rng)
virtual bool tls_verify_message(const Public_Key &key, std::string_view padding, Signature_Format format, const std::vector< uint8_t > &msg, const std::vector< uint8_t > &sig)
bool signature_used() const
Kex_Algo kex_method() const
void update(const uint8_t in[], size_t length)
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=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_hello(Server_Hello_12 *server_hello)
Callbacks & callbacks() const
const Ciphersuite & ciphersuite() const
void client_hello(Client_Hello_12 *client_hello)
std::pair< std::string, Signature_Format > choose_sig_format(const Private_Key &key, Signature_Scheme &scheme, bool for_client_auth, const Policy &policy) const
virtual void check_peer_key_acceptable(const Public_Key &public_key) const
virtual Group_Params default_dh_group() const
virtual Group_Params choose_key_exchange_group(const std::vector< Group_Params > &supported_by_peer, const std::vector< Group_Params > &offered_by_peer) const
bool verify(const Public_Key &server_key, const Handshake_State &state, const Policy &policy) const
const PK_Key_Agreement_Key & server_kex_key() const
const std::vector< uint8_t > & params() const
Server_Key_Exchange(Handshake_IO &io, Handshake_State &state, const Policy &policy, Credentials_Manager &creds, RandomNumberGenerator &rng, const Private_Key *signing_key=nullptr)
Signature_Scheme::Code wire_code() const noexcept
bool is_set() const noexcept
std::string get_string(size_t len_bytes, size_t min_bytes, size_t max_bytes)
size_t read_so_far() const
std::vector< T > get_range(size_t len_bytes, size_t min_elems, size_t max_elems)
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
std::string kex_method_to_string(Kex_Algo method)
constexpr uint8_t get_byte(T input)