Revision control
Copy as Markdown
Other Tools
/*
* TLS Messages
* (C) 2004-2011,2015 Jack Lloyd
* 2016 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_TLS_MESSAGES_12_H_
#define BOTAN_TLS_MESSAGES_12_H_
#include <botan/secmem.h>
#include <botan/tls_messages.h>
namespace Botan {
class PK_Key_Agreement_Key;
namespace TLS {
class BOTAN_UNSTABLE_API Client_Hello_12 final : public Client_Hello_12_Shim {
public:
class Settings final {
public:
explicit Settings(const Protocol_Version version, std::string_view hostname = "") :
m_new_session_version(version), m_hostname(hostname) {}
Protocol_Version protocol_version() const { return m_new_session_version; }
const std::string& hostname() const { return m_hostname; }
private:
const Protocol_Version m_new_session_version;
const std::string m_hostname;
};
public:
Client_Hello_12(Handshake_IO& io,
Handshake_Hash& hash,
const Policy& policy,
Callbacks& cb,
RandomNumberGenerator& rng,
const std::vector<uint8_t>& reneg_info,
const Settings& client_settings,
const std::vector<std::string>& next_protocols);
Client_Hello_12(Handshake_IO& io,
Handshake_Hash& hash,
const Policy& policy,
Callbacks& cb,
RandomNumberGenerator& rng,
const std::vector<uint8_t>& reneg_info,
const Session_with_Handle& session_and_handle,
const std::vector<std::string>& next_protocols);
explicit Client_Hello_12(const std::vector<uint8_t>& buf);
private:
explicit Client_Hello_12(std::unique_ptr<Client_Hello_Internal> data);
public:
using Client_Hello::compression_methods;
using Client_Hello::random;
bool prefers_compressed_ec_points() const;
bool secure_renegotiation() const;
std::vector<uint8_t> renegotiation_info() const;
bool supports_session_ticket() const;
Session_Ticket session_ticket() const;
std::optional<Session_Handle> session_handle() const;
bool supports_extended_master_secret() const;
bool supports_cert_status_message() const;
bool supports_encrypt_then_mac() const;
void update_hello_cookie(const Hello_Verify_Request& hello_verify);
private:
void add_tls12_supported_groups_extensions(const Policy& policy);
};
class BOTAN_UNSTABLE_API Server_Hello_12 final : public Server_Hello_12_Shim {
public:
class Settings final {
public:
Settings(Session_ID new_session_id,
Protocol_Version new_session_version,
uint16_t ciphersuite,
bool offer_session_ticket) :
m_new_session_id(std::move(new_session_id)),
m_new_session_version(new_session_version),
m_ciphersuite(ciphersuite),
m_offer_session_ticket(offer_session_ticket) {}
const Session_ID& session_id() const { return m_new_session_id; }
Protocol_Version protocol_version() const { return m_new_session_version; }
uint16_t ciphersuite() const { return m_ciphersuite; }
bool offer_session_ticket() const { return m_offer_session_ticket; }
private:
const Session_ID m_new_session_id;
Protocol_Version m_new_session_version;
uint16_t m_ciphersuite;
bool m_offer_session_ticket;
};
Server_Hello_12(Handshake_IO& io,
Handshake_Hash& hash,
const Policy& policy,
Callbacks& cb,
RandomNumberGenerator& rng,
const std::vector<uint8_t>& secure_reneg_info,
const Client_Hello_12& client_hello,
const Settings& settings,
std::string_view next_protocol);
Server_Hello_12(Handshake_IO& io,
Handshake_Hash& hash,
const Policy& policy,
Callbacks& cb,
RandomNumberGenerator& rng,
const std::vector<uint8_t>& secure_reneg_info,
const Client_Hello_12& client_hello,
const Session& resumed_session,
bool offer_session_ticket,
std::string_view next_protocol);
explicit Server_Hello_12(const std::vector<uint8_t>& buf);
private:
explicit Server_Hello_12(std::unique_ptr<Server_Hello_Internal> data);
public:
using Server_Hello::compression_method;
using Server_Hello::extension_types;
using Server_Hello::legacy_version;
using Server_Hello::random;
bool secure_renegotiation() const;
std::vector<uint8_t> renegotiation_info() const;
std::string next_protocol() const;
bool supports_extended_master_secret() const;
bool supports_encrypt_then_mac() const;
bool supports_certificate_status_message() const;
bool supports_session_ticket() const;
uint16_t srtp_profile() const;
bool prefers_compressed_ec_points() const;
};
/**
* Client Key Exchange Message
*/
class BOTAN_UNSTABLE_API Client_Key_Exchange final : public Handshake_Message {
public:
Handshake_Type type() const override { return Handshake_Type::ClientKeyExchange; }
const secure_vector<uint8_t>& pre_master_secret() const { return m_pre_master; }
/**
* @returns the agreed upon PSK identity or std::nullopt if not applicable
*/
const std::optional<std::string>& psk_identity() const { return m_psk_identity; }
Client_Key_Exchange(Handshake_IO& io,
Handshake_State& state,
const Policy& policy,
Credentials_Manager& creds,
const Public_Key* server_public_key,
std::string_view hostname,
RandomNumberGenerator& rng);
Client_Key_Exchange(const std::vector<uint8_t>& buf,
const Handshake_State& state,
const Private_Key* server_rsa_kex_key,
Credentials_Manager& creds,
const Policy& policy,
RandomNumberGenerator& rng);
private:
std::vector<uint8_t> serialize() const override { return m_key_material; }
std::vector<uint8_t> m_key_material;
secure_vector<uint8_t> m_pre_master;
std::optional<std::string> m_psk_identity;
};
/**
* Certificate Message of TLS 1.2
*/
class BOTAN_UNSTABLE_API Certificate_12 final : public Handshake_Message /* NOLINT(*-special-member-functions) */ {
public:
Handshake_Type type() const override { return Handshake_Type::Certificate; }
const std::vector<X509_Certificate>& cert_chain() const { return m_certs; }
size_t count() const;
bool empty() const { return m_certs.empty(); }
Certificate_12(Handshake_IO& io, Handshake_Hash& hash, const std::vector<X509_Certificate>& certs);
Certificate_12(const std::vector<uint8_t>& buf, const Policy& policy);
~Certificate_12() override;
std::vector<uint8_t> serialize() const override;
private:
std::vector<X509_Certificate> m_certs;
};
/**
* Certificate Request Message (TLS 1.2)
*/
class BOTAN_UNSTABLE_API Certificate_Request_12 final : public Handshake_Message {
public:
Handshake_Type type() const override;
const std::vector<std::string>& acceptable_cert_types() const;
const std::vector<X509_DN>& acceptable_CAs() const;
const std::vector<Signature_Scheme>& signature_schemes() const;
Certificate_Request_12(Handshake_IO& io,
Handshake_Hash& hash,
const Policy& policy,
const std::vector<X509_DN>& allowed_cas);
explicit Certificate_Request_12(const std::vector<uint8_t>& buf);
~Certificate_Request_12() override;
Certificate_Request_12(const Certificate_Request_12&) = delete;
Certificate_Request_12(Certificate_Request_12&&) = delete;
Certificate_Request_12& operator=(const Certificate_Request_12& other) = delete;
Certificate_Request_12& operator=(Certificate_Request_12&& other) = delete;
std::vector<uint8_t> serialize() const override;
private:
std::vector<X509_DN> m_names;
std::vector<std::string> m_cert_key_types;
std::vector<Signature_Scheme> m_schemes;
};
/**
* Certificate Verify Message
*/
class BOTAN_UNSTABLE_API Certificate_Verify_12 final : public Certificate_Verify {
public:
using Certificate_Verify::Certificate_Verify;
Certificate_Verify_12(Handshake_IO& io,
Handshake_State& state,
const Policy& policy,
RandomNumberGenerator& rng,
const Private_Key* key);
/**
* Check the signature on a certificate verify message
* @param cert the purported certificate
* @param state the handshake state
* @param policy the TLS policy
*/
bool verify(const X509_Certificate& cert, const Handshake_State& state, const Policy& policy) const;
};
/**
* Certificate Status (RFC 6066)
*/
class BOTAN_UNSTABLE_API Certificate_Status_12 final : public Certificate_Status {
public:
/*
* Create a Certificate_Status message using an already DER encoded OCSP response.
*/
Certificate_Status_12(Handshake_IO& io, Handshake_Hash& hash, std::vector<uint8_t> raw_response_bytes);
};
class BOTAN_UNSTABLE_API Finished_12 final : public Finished {
public:
using Finished::Finished;
Finished_12(Handshake_IO& io, Handshake_State& state, Connection_Side side);
bool verify(const Handshake_State& state, Connection_Side side) const;
};
/**
* Hello Request Message
*/
class BOTAN_UNSTABLE_API Hello_Request final : public Handshake_Message {
public:
Handshake_Type type() const override { return Handshake_Type::HelloRequest; }
explicit Hello_Request(Handshake_IO& io);
explicit Hello_Request(const std::vector<uint8_t>& buf);
private:
std::vector<uint8_t> serialize() const override;
};
/**
* Server Key Exchange Message
*/
class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message {
public:
Handshake_Type type() const override { return Handshake_Type::ServerKeyExchange; }
const std::vector<uint8_t>& params() const { return m_params; }
bool verify(const Public_Key& server_key, const Handshake_State& state, const Policy& policy) const;
// Only valid for certain kex types
const PK_Key_Agreement_Key& server_kex_key() const;
/**
* @returns the agreed upon KEX group or std::nullopt if the KEX type does
* not depend on a group
*/
const std::optional<Group_Params>& shared_group() const { return m_shared_group; }
Server_Key_Exchange(Handshake_IO& io,
Handshake_State& state,
const Policy& policy,
Credentials_Manager& creds,
RandomNumberGenerator& rng,
const Private_Key* signing_key = nullptr);
Server_Key_Exchange(const std::vector<uint8_t>& buf,
Kex_Algo kex_alg,
Auth_Method sig_alg,
Protocol_Version version);
~Server_Key_Exchange() override;
Server_Key_Exchange(const Server_Key_Exchange& other) = delete;
Server_Key_Exchange(Server_Key_Exchange&& other) = delete;
Server_Key_Exchange& operator=(const Server_Key_Exchange& other) = delete;
Server_Key_Exchange& operator=(Server_Key_Exchange&& other) = delete;
private:
std::vector<uint8_t> serialize() const override;
std::unique_ptr<PK_Key_Agreement_Key> m_kex_key;
std::optional<Group_Params> m_shared_group;
std::vector<uint8_t> m_params;
std::vector<uint8_t> m_signature;
Signature_Scheme m_scheme;
};
/**
* Server Hello Done Message
*/
class BOTAN_UNSTABLE_API Server_Hello_Done final : public Handshake_Message {
public:
Handshake_Type type() const override { return Handshake_Type::ServerHelloDone; }
explicit Server_Hello_Done(Handshake_IO& io, Handshake_Hash& hash);
explicit Server_Hello_Done(const std::vector<uint8_t>& buf);
private:
std::vector<uint8_t> serialize() const override;
};
/**
* New Session Ticket Message
*/
class BOTAN_UNSTABLE_API New_Session_Ticket_12 final : public Handshake_Message {
public:
Handshake_Type type() const override { return Handshake_Type::NewSessionTicket; }
uint32_t ticket_lifetime_hint() const { return m_ticket_lifetime_hint; }
const Session_Ticket& ticket() const { return m_ticket; }
New_Session_Ticket_12(Handshake_IO& io,
Handshake_Hash& hash,
Session_Ticket ticket,
uint32_t lifetime_in_seconds);
New_Session_Ticket_12(Handshake_IO& io, Handshake_Hash& hash);
explicit New_Session_Ticket_12(const std::vector<uint8_t>& buf);
std::vector<uint8_t> serialize() const override;
private:
uint32_t m_ticket_lifetime_hint = 0;
Session_Ticket m_ticket;
};
/**
* Change Cipher Spec
*/
class BOTAN_UNSTABLE_API Change_Cipher_Spec final : public Handshake_Message {
public:
Handshake_Type type() const override { return Handshake_Type::HandshakeCCS; }
std::vector<uint8_t> serialize() const override { return std::vector<uint8_t>(1, 1); }
};
} // namespace TLS
} // namespace Botan
#endif