aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2011-12-27 19:25:36 +0000
committerlloyd <[email protected]>2011-12-27 19:25:36 +0000
commit4f8d9afee56cb65f0fde306d9af8a2d0aea37c53 (patch)
treead68c2c73d97626cc464d94d6e9999d039141b00
parentd470084173f251e0c319dfc30d7eca40be9d5824 (diff)
Half of session serialization
-rw-r--r--src/tls/info.txt1
-rw-r--r--src/tls/tls_server.cpp36
-rw-r--r--src/tls/tls_session_key.cpp2
-rw-r--r--src/tls/tls_session_state.cpp100
-rw-r--r--src/tls/tls_session_state.h119
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;