diff options
author | lloyd <[email protected]> | 2011-12-28 12:58:12 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2011-12-28 12:58:12 +0000 |
commit | 83ebcf2351b6cf9c8320bbe6fe87e307e40577dc (patch) | |
tree | 42975093410643662033245228c9c744ddcc62ad | |
parent | e2f2809a421c8e9d60217cefdf2503a887e582ca (diff) |
Make TLS_Session_Params a real class. Various cleanups.
-rw-r--r-- | src/tls/hello.cpp | 15 | ||||
-rw-r--r-- | src/tls/tls_magic.h | 5 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 16 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 46 | ||||
-rw-r--r-- | src/tls/tls_session_state.cpp | 72 | ||||
-rw-r--r-- | src/tls/tls_session_state.h | 163 |
6 files changed, 193 insertions, 124 deletions
diff --git a/src/tls/hello.cpp b/src/tls/hello.cpp index 51601db08..1312d075a 100644 --- a/src/tls/hello.cpp +++ b/src/tls/hello.cpp @@ -8,6 +8,7 @@ #include <botan/internal/tls_messages.h> #include <botan/internal/tls_reader.h> #include <botan/internal/tls_session_key.h> +#include <botan/tls_record.h> namespace Botan { @@ -71,7 +72,7 @@ Client_Hello::Client_Hello(RandomNumberGenerator& rng, c_random = rng.random_vec(32); suites = policy.ciphersuites(); - comp_algos = policy.compression(); + comp_methods = policy.compression(); c_version = policy.pref_version(); send(writer, hash); @@ -90,7 +91,7 @@ MemoryVector<byte> Client_Hello::serialize() const append_tls_length_value(buf, sess_id, 1); append_tls_length_value(buf, suites, 2); - append_tls_length_value(buf, comp_algos, 1); + append_tls_length_value(buf, comp_methods, 1); return buf; } @@ -150,7 +151,7 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf) suites = reader.get_range_vector<u16bit>(2, 1, 32767); - comp_algos = reader.get_range_vector<byte>(1, 1, 255); + comp_methods = reader.get_range_vector<byte>(1, 1, 255); if(reader.has_remaining()) { @@ -251,7 +252,7 @@ Server_Hello::Server_Hello(RandomNumberGenerator& rng, throw TLS_Exception(PROTOCOL_VERSION, "Can't agree on a ciphersuite with client"); - comp_algo = policy.choose_compression(c_hello.compression_algos()); + comp_method = policy.choose_compression(c_hello.compression_methods()); send(writer, hash); } @@ -270,7 +271,7 @@ Server_Hello::Server_Hello(RandomNumberGenerator& rng, sess_id(session_id), s_random(rng.random_vec(32)), suite(ciphersuite), - comp_algo(compression) + comp_method(compression) { send(writer, hash); } @@ -291,7 +292,7 @@ MemoryVector<byte> Server_Hello::serialize() const buf.push_back(get_byte(0, suite)); buf.push_back(get_byte(1, suite)); - buf.push_back(comp_algo); + buf.push_back(comp_method); return buf; } @@ -320,7 +321,7 @@ void Server_Hello::deserialize(const MemoryRegion<byte>& buf) suite = reader.get_u16bit(); - comp_algo = reader.get_byte(); + comp_method = reader.get_byte(); } /* diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h index 070fe4dd6..805519787 100644 --- a/src/tls/tls_magic.h +++ b/src/tls/tls_magic.h @@ -168,8 +168,9 @@ enum TLS_Ciphersuite_Algos { TLS_ALGO_CIPHER_SEED_CBC = 0x00000005 }; -enum Compression_Algo { - NO_COMPRESSION = 0x00 +enum Compression_Method { + NO_COMPRESSION = 0x00, + DEFLATE_COMPRESSION = 0x01 }; enum TLS_Handshake_Extension_Type { diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 4d172fbcf..c4920066e 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -8,9 +8,10 @@ #ifndef BOTAN_TLS_MESSAGES_H__ #define BOTAN_TLS_MESSAGES_H__ -#include <botan/tls_record.h> #include <botan/internal/tls_handshake_hash.h> #include <botan/tls_policy.h> +#include <botan/tls_magic.h> +#include <botan/tls_suites.h> #include <botan/bigint.h> #include <botan/pkcs8.h> #include <botan/x509cert.h> @@ -18,6 +19,9 @@ namespace Botan { +class Record_Writer; +class Record_Reader; + /** * TLS Handshake Message Base Class */ @@ -53,11 +57,11 @@ class Client_Hello : public HandshakeMessage } std::vector<u16bit> ciphersuites() const { return suites; } - std::vector<byte> compression_algos() const { return comp_algos; } + std::vector<byte> compression_methods() const { return comp_methods; } const MemoryVector<byte>& random() const { return c_random; } - std::string hostname() const { return requested_hostname; } + std::string sni_hostname() const { return requested_hostname; } std::string srp_identifier() const { return requested_srp_id; } @@ -83,7 +87,7 @@ class Client_Hello : public HandshakeMessage Version_Code c_version; MemoryVector<byte> sess_id, c_random; std::vector<u16bit> suites; - std::vector<byte> comp_algos; + std::vector<byte> comp_methods; std::string requested_hostname; std::string requested_srp_id; }; @@ -242,7 +246,7 @@ class Server_Hello : public HandshakeMessage Version_Code version() { return s_version; } const MemoryVector<byte>& session_id() const { return sess_id; } u16bit ciphersuite() const { return suite; } - byte compression_algo() const { return comp_algo; } + byte compression_method() const { return comp_method; } std::vector<byte> session_id_vector() const { @@ -278,7 +282,7 @@ class Server_Hello : public HandshakeMessage Version_Code s_version; MemoryVector<byte> sess_id, s_random; u16bit suite; - byte comp_algo; + byte comp_method; }; /** diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index e0fdb6ea7..f9de0a2b6 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -36,23 +36,41 @@ bool check_for_resume(TLS_Session_Params& session_info, { MemoryVector<byte> client_session_id = client_hello->session_id(); - if(client_session_id.empty()) + if(client_session_id.empty()) // not resuming return false; - if(!session_manager.find(client_session_id, session_info, SERVER)) + // wrong side + if(!session_manager.find(client_session_id, session_info)) return false; - if(client_hello->version() != session_info.version) + // wrong version + if(client_hello->version() != session_info.version()) return false; + // client didn't send original ciphersuite if(!value_exists(client_hello->ciphersuites(), - session_info.ciphersuite)) + session_info.ciphersuite())) return false; - if(!value_exists(client_hello->compression_algos(), - session_info.compression_method)) + // client didn't send original compression method + if(!value_exists(client_hello->compression_methods(), + session_info.compression_method())) return false; + // client send a different SRP identity (!!!) + if(client_hello->srp_identifier() != "") + { + if(client_hello->srp_identifier() != session_info.srp_identifier()) + return false; + } + + // client send a different SNI hostname (!!!) + if(client_hello->sni_hostname() != "") + { + if(client_hello->sni_hostname() != session_info.sni_hostname()) + return false; + } + return true; } @@ -133,7 +151,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, { state->client_hello = new Client_Hello(contents, type); - client_requested_hostname = state->client_hello->hostname(); + client_requested_hostname = state->client_hello->sni_hostname(); state->version = choose_version(state->client_hello->version(), policy.min_version()); @@ -152,16 +170,16 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->server_hello = new Server_Hello( rng, writer, - session_info.session_id, - session_info.ciphersuite, - session_info.compression_method, - Version_Code(session_info.version), + session_info.session_id(), + session_info.ciphersuite(), + session_info.compression_method(), + Version_Code(session_info.version()), state->hash); state->suite = CipherSuite(state->server_hello->ciphersuite()); state->keys = SessionKeys(state->suite, state->version, - session_info.master_secret, + session_info.master_secret(), state->client_hello->random(), state->server_hello->random(), true); @@ -275,7 +293,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, std::vector<X509_Certificate> client_certs = state->client_certs->cert_chain(); - const bool ok = state->client_verify->verify(client_certs[0] + //const bool ok = state->client_verify->verify(client_certs[0]); state->set_expected_next(HANDSHAKE_CCS); } @@ -321,7 +339,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->keys.master_secret(), state->server_hello->version(), state->server_hello->ciphersuite(), - state->server_hello->compression_algo(), + state->server_hello->compression_method(), SERVER, 0, client_requested_hostname, diff --git a/src/tls/tls_session_state.cpp b/src/tls/tls_session_state.cpp index 47c7d8f5f..dd2c91c70 100644 --- a/src/tls/tls_session_state.cpp +++ b/src/tls/tls_session_state.cpp @@ -13,7 +13,7 @@ namespace Botan { -TLS_Session_Params::TLS_Session_Params(const MemoryRegion<byte>& session_id, +TLS_Session_Params::TLS_Session_Params(const MemoryRegion<byte>& session_identifier, const MemoryRegion<byte>& master_secret, Version_Code version, u16bit ciphersuite, @@ -21,19 +21,19 @@ TLS_Session_Params::TLS_Session_Params(const MemoryRegion<byte>& session_id, Connection_Side side, const X509_Certificate* cert, const std::string& sni_hostname, - const std::string& srp_identity) : + const std::string& srp_identifier) : session_start_time(system_time()), - session_id(session_id), - master_secret(master_secret), - version(version), - ciphersuite(ciphersuite), - compression_method(compression_method), - connection_side(side), - sni_hostname(sni_hostname), - srp_identity(srp_identity) + session_identifier(session_identifier), + session_master_secret(master_secret), + session_version(version), + session_ciphersuite(ciphersuite), + session_compression_method(compression_method), + session_connection_side(side), + session_sni_hostname(sni_hostname), + session_srp_identifier(srp_identifier) { if(cert) - peer_certificate = cert->BER_encode(); + session_peer_certificate = cert->BER_encode(); } TLS_Session_Params::TLS_Session_Params(const byte ber[], size_t ber_len) @@ -42,25 +42,25 @@ TLS_Session_Params::TLS_Session_Params(const byte ber[], size_t ber_len) byte side_code = 0; ASN1_String sni_hostname_str; - ASN1_String srp_identity_str; + ASN1_String srp_identifier_str; BER_Decoder(ber, ber_len) .decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION), "Unknown version in session structure") - .decode(session_id, OCTET_STRING) + .decode(session_identifier, OCTET_STRING) .decode_integer_type(session_start_time) - .decode_integer_type(version) - .decode_integer_type(ciphersuite) - .decode_integer_type(compression_method) + .decode_integer_type(session_version) + .decode_integer_type(session_ciphersuite) + .decode_integer_type(session_compression_method) .decode_integer_type(side_code) - .decode(master_secret, OCTET_STRING) - .decode(peer_certificate, OCTET_STRING) + .decode(session_master_secret, OCTET_STRING) + .decode(session_peer_certificate, OCTET_STRING) .decode(sni_hostname_str) - .decode(srp_identity_str); + .decode(srp_identifier_str); - sni_hostname = sni_hostname_str.value(); - srp_identity = srp_identity_str.value(); - connection_side = static_cast<Connection_Side>(side_code); + session_sni_hostname = sni_hostname_str.value(); + session_srp_identifier = srp_identifier_str.value(); + session_connection_side = static_cast<Connection_Side>(side_code); } SecureVector<byte> TLS_Session_Params::BER_encode() const @@ -68,23 +68,22 @@ SecureVector<byte> TLS_Session_Params::BER_encode() const return DER_Encoder() .start_cons(SEQUENCE) .encode(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION)) - .encode(session_id, OCTET_STRING) + .encode(session_identifier, OCTET_STRING) .encode(static_cast<size_t>(session_start_time)) - .encode(static_cast<size_t>(version)) - .encode(static_cast<size_t>(ciphersuite)) - .encode(static_cast<size_t>(compression_method)) - .encode(static_cast<size_t>(connection_side)) - .encode(master_secret, OCTET_STRING) - .encode(peer_certificate, OCTET_STRING) - .encode(ASN1_String(sni_hostname, UTF8_STRING)) - .encode(ASN1_String(srp_identity, UTF8_STRING)) + .encode(static_cast<size_t>(session_version)) + .encode(static_cast<size_t>(session_ciphersuite)) + .encode(static_cast<size_t>(session_compression_method)) + .encode(static_cast<size_t>(session_connection_side)) + .encode(session_master_secret, OCTET_STRING) + .encode(session_peer_certificate, OCTET_STRING) + .encode(ASN1_String(session_sni_hostname, UTF8_STRING)) + .encode(ASN1_String(session_srp_identifier, UTF8_STRING)) .end_cons() .get_contents(); } bool TLS_Session_Manager_In_Memory::find(const MemoryVector<byte>& session_id, - TLS_Session_Params& params, - Connection_Side side) + TLS_Session_Params& params) { std::map<std::string, TLS_Session_Params>::iterator i = sessions.find(hex_encode(session_id)); @@ -94,15 +93,12 @@ bool TLS_Session_Manager_In_Memory::find(const MemoryVector<byte>& session_id, // session has expired, remove it const u64bit now = system_time(); - if(i->second.session_start_time + session_lifetime >= now) + if(i->second.start_time() + session_lifetime >= now) { sessions.erase(i); return false; } - if(i->second.connection_side != side) - return false; - params = i->second; return true; } @@ -128,7 +124,7 @@ void TLS_Session_Manager_In_Memory::save(const TLS_Session_Params& session_data) sessions.erase(sessions.begin()); } - sessions[hex_encode(session_data.session_id)] = session_data; + sessions[hex_encode(session_data.session_id())] = session_data; } } diff --git a/src/tls/tls_session_state.h b/src/tls/tls_session_state.h index f42a7ac11..93793c882 100644 --- a/src/tls/tls_session_state.h +++ b/src/tls/tls_session_state.h @@ -20,59 +20,111 @@ namespace Botan { /** * Class representing a TLS session state */ -struct BOTAN_DLL TLS_Session_Params +class BOTAN_DLL TLS_Session_Params { - enum { TLS_SESSION_PARAM_STRUCT_VERSION = 1 }; - - /** - * Uninitialized session - */ - TLS_Session_Params() : - session_start_time(0), - version(0), - ciphersuite(0), - compression_method(0), - connection_side(static_cast<Connection_Side>(0)) - {} - - /** - * New session (sets session start time) - */ - TLS_Session_Params(const MemoryRegion<byte>& session_id, - const MemoryRegion<byte>& master_secret, - Version_Code version, - u16bit ciphersuite, - byte compression_method, - Connection_Side side, - const X509_Certificate* cert = 0, - const std::string& sni_hostname = "", - const std::string& srp_identity = ""); - - /** - * Load a session from BER (created by BER_encode) - */ - TLS_Session_Params(const byte ber[], size_t ber_len); - - /** - * Encode this session data for storage - * @warning if the master secret is compromised so is the - * session traffic - */ - SecureVector<byte> BER_encode() const; - - u64bit session_start_time; - - MemoryVector<byte> session_id; - SecureVector<byte> master_secret; - - u16bit version; - u16bit ciphersuite; - byte compression_method; - Connection_Side connection_side; - - MemoryVector<byte> peer_certificate; // optional - std::string sni_hostname; // optional - std::string srp_identity; // optional + public: + + /** + * Uninitialized session + */ + TLS_Session_Params() : + session_start_time(0), + session_version(0), + session_ciphersuite(0), + session_compression_method(0), + session_connection_side(static_cast<Connection_Side>(0)) + {} + + /** + * New session (sets session start time) + */ + TLS_Session_Params(const MemoryRegion<byte>& session_id, + const MemoryRegion<byte>& master_secret, + Version_Code version, + u16bit ciphersuite, + byte compression_method, + Connection_Side side, + const X509_Certificate* cert = 0, + const std::string& sni_hostname = "", + const std::string& srp_identifier = ""); + + /** + * Load a session from BER (created by BER_encode) + */ + TLS_Session_Params(const byte ber[], size_t ber_len); + + /** + * Encode this session data for storage + * @warning if the master secret is compromised so is the + * session traffic + */ + SecureVector<byte> BER_encode() const; + + /** + * Get the version of the saved session + */ + Version_Code version() const + { return static_cast<Version_Code>(session_version); } + + /** + * Get the ciphersuite of the saved session + */ + u16bit ciphersuite() const { return session_ciphersuite; } + + /** + * Get the compression method used in the saved session + */ + byte compression_method() const { return session_compression_method; } + + /** + * Get which side of the connection the resumed session we are/were + * acting as. + */ + Connection_Side side() const { return session_connection_side; } + + /** + * Get the SNI hostname (if sent by the client in the initial handshake) + */ + std::string sni_hostname() const { return session_sni_hostname; } + + /** + * Get the SRP identity (if sent by the client in the initial handshake) + */ + std::string srp_identifier() const { return session_srp_identifier; } + + /** + * Get the saved master secret + */ + const SecureVector<byte>& master_secret() const + { return session_master_secret; } + + /** + * Get the session identifier + */ + const MemoryVector<byte>& session_id() const + { return session_identifier; } + + /** + * Get the time this session began (seconds since Epoch) + */ + u64bit start_time() const { return session_start_time; } + + private: + enum { TLS_SESSION_PARAM_STRUCT_VERSION = 1 }; + + u64bit session_start_time; + + MemoryVector<byte> session_identifier; + SecureVector<byte> session_master_secret; + + u16bit session_version; + u16bit session_ciphersuite; + byte session_compression_method; + Connection_Side session_connection_side; + + MemoryVector<byte> session_peer_certificate; // optional + std::string session_sni_hostname; // optional + std::string session_srp_identifier; // optional }; /** @@ -89,12 +141,10 @@ class BOTAN_DLL TLS_Session_Manager * @param session_id the session identifier we are trying to resume * @param params will be set to the saved session data (if found), or not modified if not found - * @param which side of the connection we are * @return true if params was modified */ virtual bool find(const MemoryVector<byte>& session_id, - TLS_Session_Params& params, - Connection_Side side) = 0; + TLS_Session_Params& params) = 0; /** * Prohibit resumption of this session. Effectively an erase. @@ -137,8 +187,7 @@ class BOTAN_DLL TLS_Session_Manager_In_Memory : public TLS_Session_Manager {} bool find(const MemoryVector<byte>& session_id, - TLS_Session_Params& params, - Connection_Side side); + TLS_Session_Params& params); void prohibit_resumption(const MemoryVector<byte>& session_id); |