diff options
author | lloyd <[email protected]> | 2011-12-27 19:25:36 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2011-12-27 19:25:36 +0000 |
commit | 4f8d9afee56cb65f0fde306d9af8a2d0aea37c53 (patch) | |
tree | ad68c2c73d97626cc464d94d6e9999d039141b00 | |
parent | d470084173f251e0c319dfc30d7eca40be9d5824 (diff) |
Half of session serialization
-rw-r--r-- | src/tls/info.txt | 1 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 36 | ||||
-rw-r--r-- | src/tls/tls_session_key.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_session_state.cpp | 100 | ||||
-rw-r--r-- | src/tls/tls_session_state.h | 119 |
5 files changed, 181 insertions, 77 deletions
diff --git a/src/tls/info.txt b/src/tls/info.txt index a088ed4fb..b6184b69a 100644 --- a/src/tls/info.txt +++ b/src/tls/info.txt @@ -43,6 +43,7 @@ tls_client.cpp tls_policy.cpp tls_server.cpp tls_session_key.cpp +tls_session_state.cpp tls_state.cpp tls_suites.cpp </source> diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 9e0b07169..67db0f593 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -11,6 +11,7 @@ #include <botan/dh.h> #include <stdio.h> +#include <fstream> namespace Botan { @@ -115,11 +116,12 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, writer.set_version(state->version); reader.set_version(state->version); + MemoryVector<byte> client_session_id = state->client_hello->session_id(); + TLS_Session_Params session_info; const bool resuming = - state->client_hello->session_id_vector().size() && - session_manager.find(state->client_hello->session_id_vector(), - session_info, SERVER); + (!client_session_id.empty()) && + session_manager.find(client_session_id, session_info, SERVER); printf("Resuming ? %d\n", resuming); @@ -283,16 +285,24 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->keys.master_secret(), state->hash); - TLS_Session_Params session_info; - - session_info.version = state->server_hello->version(); - session_info.connection_side = SERVER; - session_info.ciphersuite = state->server_hello->ciphersuite(); - session_info.compression_method = state->server_hello->compression_algo(); - session_info.master_secret = state->keys.master_secret(); - - session_manager.save(state->server_hello->session_id_vector(), - session_info); + TLS_Session_Params session_info( + state->server_hello->session_id(), + state->keys.master_secret(), + state->server_hello->version(), + state->server_hello->ciphersuite(), + state->server_hello->compression_algo(), + SERVER, + 0, + client_requested_hostname, + "" + ); + + session_manager.save(session_info); + + std::ofstream tmp("/tmp/session.data"); + SecureVector<byte> b = session_info.BER_encode(); + tmp.write((char*)&b[0], b.size()); + tmp.close(); } delete state; diff --git a/src/tls/tls_session_key.cpp b/src/tls/tls_session_key.cpp index 01e74ba69..93615c7ce 100644 --- a/src/tls/tls_session_key.cpp +++ b/src/tls/tls_session_key.cpp @@ -6,8 +6,6 @@ */ #include <botan/tls_session_key.h> -#include <botan/prf_ssl3.h> -#include <botan/prf_tls.h> #include <botan/lookup.h> #include <memory> diff --git a/src/tls/tls_session_state.cpp b/src/tls/tls_session_state.cpp new file mode 100644 index 000000000..1423ac09d --- /dev/null +++ b/src/tls/tls_session_state.cpp @@ -0,0 +1,100 @@ +/* +* TLS Session Management +* (C) 2011 Jack Lloyd +* +* Released under the terms of the Botan license +*/ + +#include <botan/tls_session_state.h> +#include <botan/der_enc.h> +#include <botan/ber_dec.h> +#include <botan/asn1_str.h> +#include <botan/bigint.h> +#include <ctime> + +namespace Botan { + +TLS_Session_Params::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, + const std::string& sni_hostname, + const std::string& srp_identity) : + session_start_time(time(0)), + 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) + { + if(cert) + peer_certificate = cert->BER_encode(); + } + +TLS_Session_Params::TLS_Session_Params(const byte ber[], size_t ber_len) + { + // todo + } + +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(BigInt(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 == SERVER) ? 1 : 2)) + .encode(master_secret, OCTET_STRING) + .encode(peer_certificate, OCTET_STRING) + .encode(ASN1_String(sni_hostname, UTF8_STRING)) + .encode(ASN1_String(srp_identity, 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) + { + std::map<std::string, TLS_Session_Params>::const_iterator i = + sessions.find(hex_encode(session_id)); + + if(i != sessions.end() && i->second.connection_side == side) + { + params = i->second; + return true; + } + + return false; + } + +void TLS_Session_Manager_In_Memory::prohibit_resumption(const MemoryVector<byte>& session_id) + { + std::map<std::string, TLS_Session_Params>::iterator i = + sessions.find(hex_encode(session_id)); + + if(i != sessions.end()) + sessions.erase(i); + } + +void TLS_Session_Manager_In_Memory::save(const TLS_Session_Params& session_data) + { + if(max_sessions != 0) + { + while(sessions.size() >= max_sessions) + sessions.erase(sessions.begin()); + } + + 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 343351e2c..20cbb7f83 100644 --- a/src/tls/tls_session_state.h +++ b/src/tls/tls_session_state.h @@ -8,29 +8,71 @@ #ifndef TLS_SESSION_STATE_H_ #define TLS_SESSION_STATE_H_ +#include <botan/x509cert.h> #include <botan/tls_magic.h> #include <botan/secmem.h> #include <botan/hex.h> -#include <vector> #include <map> - -#include <iostream> +#include <ctime> namespace Botan { /** * Class representing a TLS session state -* -* @todo Support serialization to make it easier for session managers */ struct 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; + + time_t session_start_time; + + MemoryVector<byte> session_id; + SecureVector<byte> master_secret; + u16bit version; u16bit ciphersuite; byte compression_method; Connection_Side connection_side; - SecureVector<byte> master_secret; + MemoryVector<byte> peer_certificate; // optional + std::string sni_hostname; // optional + std::string srp_identity; // optional }; /** @@ -50,14 +92,14 @@ class BOTAN_DLL TLS_Session_Manager * @param which side of the connection we are * @return true if params was modified */ - virtual bool find(const std::vector<byte>& session_id, + virtual bool find(const MemoryVector<byte>& session_id, TLS_Session_Params& params, Connection_Side side) = 0; /** * Prohibit resumption of this session. Effectively an erase. */ - virtual void prohibit_resumption(const std::vector<byte>& session_id) = 0; + virtual void prohibit_resumption(const MemoryVector<byte>& session_id) = 0; /** * Save a session on a best effort basis; the manager may not in @@ -68,8 +110,7 @@ class BOTAN_DLL TLS_Session_Manager * @param session_id the session identifier * @param params to save */ - virtual void save(const std::vector<byte>& session_id, - const TLS_Session_Params& params) = 0; + virtual void save(const TLS_Session_Params& params) = 0; virtual ~TLS_Session_Manager() {} }; @@ -89,65 +130,19 @@ class BOTAN_DLL TLS_Session_Manager_In_Memory : public TLS_Session_Manager * @param session_lifetime sesions are expired after this many * seconds have elapsed. */ - TLS_Session_Manager_In_Memory(size_t max_sessions = 10000, - size_t session_lifetime = 86400) : + TLS_Session_Manager_In_Memory(size_t max_sessions = 1000, + size_t session_lifetime = 300) : max_sessions(max_sessions), session_lifetime(session_lifetime) {} - bool find(const std::vector<byte>& session_id, + bool find(const MemoryVector<byte>& session_id, TLS_Session_Params& params, - Connection_Side side) - { - const std::string session_id_str = - hex_encode(&session_id[0], session_id.size()); - - std::map<std::string, TLS_Session_Params>::const_iterator i = - sessions.find(session_id_str); - - std::cout << "Client asked about " << session_id_str << "\n"; - - std::cout << "Know about " << sessions.size() << " sessions\n"; - - for(std::map<std::string, TLS_Session_Params>::const_iterator j = - sessions.begin(); j != sessions.end(); ++j) - std::cout << "Session " << j->first << "\n"; - - if(i != sessions.end() && i->second.connection_side == side) - { - params = i->second; - return true; - } - - return false; - } - - void prohibit_resumption(const std::vector<byte>& session_id) - { - const std::string session_id_str = - hex_encode(&session_id[0], session_id.size()); - - std::map<std::string, TLS_Session_Params>::iterator i = - sessions.find(session_id_str); - - if(i != sessions.end()) - sessions.erase(i); - } - - void save(const std::vector<byte>& session_id, - const TLS_Session_Params& session_data) - { - if(max_sessions != 0) - { - while(sessions.size() >= max_sessions) - sessions.erase(sessions.begin()); - } + Connection_Side side); - const std::string session_id_str = - hex_encode(&session_id[0], session_id.size()); + void prohibit_resumption(const MemoryVector<byte>& session_id); - sessions[session_id_str] = session_data; - } + void save(const TLS_Session_Params& session_data); private: size_t max_sessions, session_lifetime; |