/* * 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 #include 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& reneg_info, const Settings& client_settings, const std::vector& next_protocols); Client_Hello_12(Handshake_IO& io, Handshake_Hash& hash, const Policy& policy, Callbacks& cb, RandomNumberGenerator& rng, const std::vector& reneg_info, const Session_with_Handle& session_and_handle, const std::vector& next_protocols); explicit Client_Hello_12(const std::vector& buf); private: explicit Client_Hello_12(std::unique_ptr data); public: using Client_Hello::compression_methods; using Client_Hello::random; bool prefers_compressed_ec_points() const; bool secure_renegotiation() const; std::vector renegotiation_info() const; bool supports_session_ticket() const; Session_Ticket session_ticket() const; std::optional 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& 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& 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& buf); private: explicit Server_Hello_12(std::unique_ptr 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 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& pre_master_secret() const { return m_pre_master; } /** * @returns the agreed upon PSK identity or std::nullopt if not applicable */ const std::optional& 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& buf, const Handshake_State& state, const Private_Key* server_rsa_kex_key, Credentials_Manager& creds, const Policy& policy, RandomNumberGenerator& rng); private: std::vector serialize() const override { return m_key_material; } std::vector m_key_material; secure_vector m_pre_master; std::optional 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& 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& certs); Certificate_12(const std::vector& buf, const Policy& policy); ~Certificate_12() override; std::vector serialize() const override; private: std::vector 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& acceptable_cert_types() const; const std::vector& acceptable_CAs() const; const std::vector& signature_schemes() const; Certificate_Request_12(Handshake_IO& io, Handshake_Hash& hash, const Policy& policy, const std::vector& allowed_cas); explicit Certificate_Request_12(const std::vector& 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 serialize() const override; private: std::vector m_names; std::vector m_cert_key_types; std::vector 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 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& buf); private: std::vector 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& 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& 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& 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 serialize() const override; std::unique_ptr m_kex_key; std::optional m_shared_group; std::vector m_params; std::vector 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& buf); private: std::vector 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& buf); std::vector 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 serialize() const override { return std::vector(1, 1); } }; } // namespace TLS } // namespace Botan #endif