aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls/tls_messages.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/tls/tls_messages.h')
-rw-r--r--src/lib/tls/tls_messages.h567
1 files changed, 567 insertions, 0 deletions
diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h
new file mode 100644
index 000000000..155d2427b
--- /dev/null
+++ b/src/lib/tls/tls_messages.h
@@ -0,0 +1,567 @@
+/*
+* TLS Messages
+* (C) 2004-2011 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#ifndef BOTAN_TLS_MESSAGES_H__
+#define BOTAN_TLS_MESSAGES_H__
+
+#include <botan/internal/tls_handshake_state.h>
+#include <botan/internal/tls_extensions.h>
+#include <botan/tls_handshake_msg.h>
+#include <botan/tls_session.h>
+#include <botan/tls_policy.h>
+#include <botan/tls_ciphersuite.h>
+#include <botan/bigint.h>
+#include <botan/pkcs8.h>
+#include <botan/x509cert.h>
+#include <vector>
+#include <memory>
+#include <string>
+
+namespace Botan {
+
+class Credentials_Manager;
+class SRP6_Server_Session;
+
+namespace TLS {
+
+class Handshake_IO;
+
+std::vector<byte> make_hello_random(RandomNumberGenerator& rng);
+
+/**
+* DTLS Hello Verify Request
+*/
+class Hello_Verify_Request : public Handshake_Message
+ {
+ public:
+ std::vector<byte> serialize() const override;
+ Handshake_Type type() const override { return HELLO_VERIFY_REQUEST; }
+
+ std::vector<byte> cookie() const { return m_cookie; }
+
+ Hello_Verify_Request(const std::vector<byte>& buf);
+
+ Hello_Verify_Request(const std::vector<byte>& client_hello_bits,
+ const std::string& client_identity,
+ const SymmetricKey& secret_key);
+ private:
+ std::vector<byte> m_cookie;
+ };
+
+/**
+* Client Hello Message
+*/
+class Client_Hello : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return CLIENT_HELLO; }
+
+ Protocol_Version version() const { return m_version; }
+
+ const std::vector<byte>& random() const { return m_random; }
+
+ const std::vector<byte>& session_id() const { return m_session_id; }
+
+ std::vector<u16bit> ciphersuites() const { return m_suites; }
+
+ std::vector<byte> compression_methods() const { return m_comp_methods; }
+
+ bool offered_suite(u16bit ciphersuite) const;
+
+ std::vector<std::pair<std::string, std::string>> supported_algos() const
+ {
+ if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
+ return sigs->supported_signature_algorthms();
+ return std::vector<std::pair<std::string, std::string>>();
+ }
+
+ std::vector<std::string> supported_ecc_curves() const
+ {
+ if(Supported_Elliptic_Curves* ecc = m_extensions.get<Supported_Elliptic_Curves>())
+ return ecc->curves();
+ return std::vector<std::string>();
+ }
+
+ std::string sni_hostname() const
+ {
+ if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
+ return sni->host_name();
+ return "";
+ }
+
+ std::string srp_identifier() const
+ {
+ if(SRP_Identifier* srp = m_extensions.get<SRP_Identifier>())
+ return srp->identifier();
+ return "";
+ }
+
+ bool secure_renegotiation() const
+ {
+ return m_extensions.get<Renegotiation_Extension>();
+ }
+
+ std::vector<byte> renegotiation_info() const
+ {
+ if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
+ return reneg->renegotiation_info();
+ return std::vector<byte>();
+ }
+
+ bool next_protocol_notification() const
+ {
+ return m_extensions.get<Next_Protocol_Notification>();
+ }
+
+ size_t fragment_size() const
+ {
+ if(Maximum_Fragment_Length* frag = m_extensions.get<Maximum_Fragment_Length>())
+ return frag->fragment_size();
+ return 0;
+ }
+
+ bool supports_session_ticket() const
+ {
+ return m_extensions.get<Session_Ticket>();
+ }
+
+ std::vector<byte> session_ticket() const
+ {
+ if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
+ return ticket->contents();
+ return std::vector<byte>();
+ }
+
+ bool supports_heartbeats() const
+ {
+ return m_extensions.get<Heartbeat_Support_Indicator>();
+ }
+
+ bool peer_can_send_heartbeats() const
+ {
+ if(Heartbeat_Support_Indicator* hb = m_extensions.get<Heartbeat_Support_Indicator>())
+ return hb->peer_allowed_to_send();
+ return false;
+ }
+
+ void update_hello_cookie(const Hello_Verify_Request& hello_verify);
+
+ Client_Hello(Handshake_IO& io,
+ Handshake_Hash& hash,
+ Protocol_Version version,
+ const Policy& policy,
+ RandomNumberGenerator& rng,
+ const std::vector<byte>& reneg_info,
+ bool next_protocol = false,
+ const std::string& hostname = "",
+ const std::string& srp_identifier = "");
+
+ Client_Hello(Handshake_IO& io,
+ Handshake_Hash& hash,
+ const Policy& policy,
+ RandomNumberGenerator& rng,
+ const std::vector<byte>& reneg_info,
+ const Session& resumed_session,
+ bool next_protocol = false);
+
+ Client_Hello(const std::vector<byte>& buf,
+ Handshake_Type type);
+
+ private:
+ std::vector<byte> serialize() const override;
+ void deserialize(const std::vector<byte>& buf);
+ void deserialize_sslv2(const std::vector<byte>& buf);
+
+ Protocol_Version m_version;
+ std::vector<byte> m_session_id;
+ std::vector<byte> m_random;
+ std::vector<u16bit> m_suites;
+ std::vector<byte> m_comp_methods;
+ std::vector<byte> m_hello_cookie; // DTLS only
+
+ Extensions m_extensions;
+ };
+
+/**
+* Server Hello Message
+*/
+class Server_Hello : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return SERVER_HELLO; }
+
+ Protocol_Version version() const { return m_version; }
+
+ const std::vector<byte>& random() const { return m_random; }
+
+ const std::vector<byte>& session_id() const { return m_session_id; }
+
+ u16bit ciphersuite() const { return m_ciphersuite; }
+
+ byte compression_method() const { return m_comp_method; }
+
+ bool secure_renegotiation() const
+ {
+ return m_extensions.get<Renegotiation_Extension>();
+ }
+
+ std::vector<byte> renegotiation_info() const
+ {
+ if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
+ return reneg->renegotiation_info();
+ return std::vector<byte>();
+ }
+
+ bool next_protocol_notification() const
+ {
+ return m_extensions.get<Next_Protocol_Notification>();
+ }
+
+ std::vector<std::string> next_protocols() const
+ {
+ if(Next_Protocol_Notification* npn = m_extensions.get<Next_Protocol_Notification>())
+ return npn->protocols();
+ return std::vector<std::string>();
+ }
+
+ size_t fragment_size() const
+ {
+ if(Maximum_Fragment_Length* frag = m_extensions.get<Maximum_Fragment_Length>())
+ return frag->fragment_size();
+ return 0;
+ }
+
+ bool supports_session_ticket() const
+ {
+ return m_extensions.get<Session_Ticket>();
+ }
+
+ bool supports_heartbeats() const
+ {
+ return m_extensions.get<Heartbeat_Support_Indicator>();
+ }
+
+ bool peer_can_send_heartbeats() const
+ {
+ if(Heartbeat_Support_Indicator* hb = m_extensions.get<Heartbeat_Support_Indicator>())
+ return hb->peer_allowed_to_send();
+ return false;
+ }
+
+ Server_Hello(Handshake_IO& io,
+ Handshake_Hash& hash,
+ const Policy& policy,
+ const std::vector<byte>& session_id,
+ Protocol_Version ver,
+ u16bit ciphersuite,
+ byte compression,
+ size_t max_fragment_size,
+ bool client_has_secure_renegotiation,
+ const std::vector<byte>& reneg_info,
+ bool offer_session_ticket,
+ bool client_has_npn,
+ const std::vector<std::string>& next_protocols,
+ bool client_has_heartbeat,
+ RandomNumberGenerator& rng);
+
+ Server_Hello(const std::vector<byte>& buf);
+ private:
+ std::vector<byte> serialize() const override;
+
+ Protocol_Version m_version;
+ std::vector<byte> m_session_id, m_random;
+ u16bit m_ciphersuite;
+ byte m_comp_method;
+
+ Extensions m_extensions;
+ };
+
+/**
+* Client Key Exchange Message
+*/
+class Client_Key_Exchange : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return CLIENT_KEX; }
+
+ const secure_vector<byte>& pre_master_secret() const
+ { return m_pre_master; }
+
+ Client_Key_Exchange(Handshake_IO& io,
+ Handshake_State& state,
+ const Policy& policy,
+ Credentials_Manager& creds,
+ const Public_Key* server_public_key,
+ const std::string& hostname,
+ RandomNumberGenerator& rng);
+
+ Client_Key_Exchange(const std::vector<byte>& buf,
+ const Handshake_State& state,
+ const Private_Key* server_rsa_kex_key,
+ Credentials_Manager& creds,
+ const Policy& policy,
+ RandomNumberGenerator& rng);
+
+ private:
+ std::vector<byte> serialize() const override
+ { return m_key_material; }
+
+ std::vector<byte> m_key_material;
+ secure_vector<byte> m_pre_master;
+ };
+
+/**
+* Certificate Message
+*/
+class Certificate : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return CERTIFICATE; }
+ const std::vector<X509_Certificate>& cert_chain() const { return m_certs; }
+
+ size_t count() const { return m_certs.size(); }
+ bool empty() const { return m_certs.empty(); }
+
+ Certificate(Handshake_IO& io,
+ Handshake_Hash& hash,
+ const std::vector<X509_Certificate>& certs);
+
+ Certificate(const std::vector<byte>& buf);
+ private:
+ std::vector<byte> serialize() const override;
+
+ std::vector<X509_Certificate> m_certs;
+ };
+
+/**
+* Certificate Request Message
+*/
+class Certificate_Req : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return CERTIFICATE_REQUEST; }
+
+ const std::vector<std::string>& acceptable_cert_types() const
+ { return m_cert_key_types; }
+
+ std::vector<X509_DN> acceptable_CAs() const { return m_names; }
+
+ std::vector<std::pair<std::string, std::string> > supported_algos() const
+ { return m_supported_algos; }
+
+ Certificate_Req(Handshake_IO& io,
+ Handshake_Hash& hash,
+ const Policy& policy,
+ const std::vector<X509_DN>& allowed_cas,
+ Protocol_Version version);
+
+ Certificate_Req(const std::vector<byte>& buf,
+ Protocol_Version version);
+ private:
+ std::vector<byte> serialize() const override;
+
+ std::vector<X509_DN> m_names;
+ std::vector<std::string> m_cert_key_types;
+
+ std::vector<std::pair<std::string, std::string> > m_supported_algos;
+ };
+
+/**
+* Certificate Verify Message
+*/
+class Certificate_Verify : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return CERTIFICATE_VERIFY; }
+
+ /**
+ * Check the signature on a certificate verify message
+ * @param cert the purported certificate
+ * @param state the handshake state
+ */
+ bool verify(const X509_Certificate& cert,
+ const Handshake_State& state) const;
+
+ Certificate_Verify(Handshake_IO& io,
+ Handshake_State& state,
+ const Policy& policy,
+ RandomNumberGenerator& rng,
+ const Private_Key* key);
+
+ Certificate_Verify(const std::vector<byte>& buf,
+ Protocol_Version version);
+ private:
+ std::vector<byte> serialize() const override;
+
+ std::string m_sig_algo; // sig algo used to create signature
+ std::string m_hash_algo; // hash used to create signature
+ std::vector<byte> m_signature;
+ };
+
+/**
+* Finished Message
+*/
+class Finished : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return FINISHED; }
+
+ std::vector<byte> verify_data() const
+ { return m_verification_data; }
+
+ bool verify(const Handshake_State& state,
+ Connection_Side side) const;
+
+ Finished(Handshake_IO& io,
+ Handshake_State& state,
+ Connection_Side side);
+
+ Finished(const std::vector<byte>& buf);
+ private:
+ std::vector<byte> serialize() const override;
+
+ std::vector<byte> m_verification_data;
+ };
+
+/**
+* Hello Request Message
+*/
+class Hello_Request : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return HELLO_REQUEST; }
+
+ Hello_Request(Handshake_IO& io);
+ Hello_Request(const std::vector<byte>& buf);
+ private:
+ std::vector<byte> serialize() const override;
+ };
+
+/**
+* Server Key Exchange Message
+*/
+class Server_Key_Exchange : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return SERVER_KEX; }
+
+ const std::vector<byte>& params() const { return m_params; }
+
+ bool verify(const Public_Key& server_key,
+ const Handshake_State& state) const;
+
+ // Only valid for certain kex types
+ const Private_Key& server_kex_key() const;
+
+ // Only valid for SRP negotiation
+ SRP6_Server_Session& server_srp_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);
+
+ Server_Key_Exchange(const std::vector<byte>& buf,
+ const std::string& kex_alg,
+ const std::string& sig_alg,
+ Protocol_Version version);
+
+ ~Server_Key_Exchange();
+ private:
+ std::vector<byte> serialize() const override;
+
+ std::unique_ptr<Private_Key> m_kex_key;
+ std::unique_ptr<SRP6_Server_Session> m_srp_params;
+
+ std::vector<byte> m_params;
+
+ std::string m_sig_algo; // sig algo used to create signature
+ std::string m_hash_algo; // hash used to create signature
+ std::vector<byte> m_signature;
+ };
+
+/**
+* Server Hello Done Message
+*/
+class Server_Hello_Done : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return SERVER_HELLO_DONE; }
+
+ Server_Hello_Done(Handshake_IO& io, Handshake_Hash& hash);
+ Server_Hello_Done(const std::vector<byte>& buf);
+ private:
+ std::vector<byte> serialize() const override;
+ };
+
+/**
+* Next Protocol Message
+*/
+class Next_Protocol : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return NEXT_PROTOCOL; }
+
+ std::string protocol() const { return m_protocol; }
+
+ Next_Protocol(Handshake_IO& io,
+ Handshake_Hash& hash,
+ const std::string& protocol);
+
+ Next_Protocol(const std::vector<byte>& buf);
+ private:
+ std::vector<byte> serialize() const override;
+
+ std::string m_protocol;
+ };
+
+/**
+* New Session Ticket Message
+*/
+class New_Session_Ticket : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return NEW_SESSION_TICKET; }
+
+ u32bit ticket_lifetime_hint() const { return m_ticket_lifetime_hint; }
+ const std::vector<byte>& ticket() const { return m_ticket; }
+
+ New_Session_Ticket(Handshake_IO& io,
+ Handshake_Hash& hash,
+ const std::vector<byte>& ticket,
+ u32bit lifetime);
+
+ New_Session_Ticket(Handshake_IO& io,
+ Handshake_Hash& hash);
+
+ New_Session_Ticket(const std::vector<byte>& buf);
+ private:
+ std::vector<byte> serialize() const override;
+
+ u32bit m_ticket_lifetime_hint;
+ std::vector<byte> m_ticket;
+ };
+
+/**
+* Change Cipher Spec
+*/
+class Change_Cipher_Spec : public Handshake_Message
+ {
+ public:
+ Handshake_Type type() const override { return HANDSHAKE_CCS; }
+
+ std::vector<byte> serialize() const override
+ { return std::vector<byte>(1, 1); }
+ };
+
+}
+
+}
+
+#endif