Botan 2.19.1
Crypto and TLS for C&
tls_session_manager_memory.cpp
Go to the documentation of this file.
1/*
2* TLS Session Management
3* (C) 2011,2012 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/tls_session_manager.h>
9#include <botan/hex.h>
10#include <botan/rng.h>
11#include <chrono>
12
13namespace Botan {
14
15namespace TLS {
16
19 size_t max_sessions,
20 std::chrono::seconds session_lifetime) :
21 m_max_sessions(max_sessions),
22 m_session_lifetime(session_lifetime),
23 m_rng(rng),
24 m_session_key(m_rng.random_vec(32))
25 {}
26
27bool Session_Manager_In_Memory::load_from_session_str(
28 const std::string& session_str, Session& session)
29 {
30 // assert(lock is held)
31
32 auto i = m_sessions.find(session_str);
33
34 if(i == m_sessions.end())
35 return false;
36
37 try
38 {
39 session = Session::decrypt(i->second, m_session_key);
40 }
41 catch(...)
42 {
43 return false;
44 }
45
46 // if session has expired, remove it
47 const auto now = std::chrono::system_clock::now();
48
49 if(session.start_time() + session_lifetime() < now)
50 {
51 m_sessions.erase(i);
52 return false;
53 }
54
55 return true;
56 }
57
59 const std::vector<uint8_t>& session_id, Session& session)
60 {
61 lock_guard_type<mutex_type> lock(m_mutex);
62
63 return load_from_session_str(hex_encode(session_id), session);
64 }
65
67 const Server_Information& info, Session& session)
68 {
69 lock_guard_type<mutex_type> lock(m_mutex);
70
71 auto i = m_info_sessions.find(info);
72
73 if(i == m_info_sessions.end())
74 return false;
75
76 if(load_from_session_str(i->second, session))
77 return true;
78
79 /*
80 * It existed at one point but was removed from the sessions map,
81 * remove m_info_sessions entry as well
82 */
83 m_info_sessions.erase(i);
84
85 return false;
86 }
87
89 const std::vector<uint8_t>& session_id)
90 {
91 lock_guard_type<mutex_type> lock(m_mutex);
92
93 auto i = m_sessions.find(hex_encode(session_id));
94
95 if(i != m_sessions.end())
96 m_sessions.erase(i);
97 }
98
100 {
101 const size_t removed = m_sessions.size();
102 m_info_sessions.clear();
103 m_sessions.clear();
104 m_rng.random_vec(m_session_key, 32);
105 return removed;
106 }
107
109 {
110 lock_guard_type<mutex_type> lock(m_mutex);
111
112 if(m_max_sessions != 0)
113 {
114 /*
115 We generate new session IDs with the first 4 bytes being a
116 timestamp, so this actually removes the oldest sessions first.
117 */
118 while(m_sessions.size() >= m_max_sessions)
119 m_sessions.erase(m_sessions.begin());
120 }
121
122 const std::string session_id_str = hex_encode(session.session_id());
123
124 m_sessions[session_id_str] = session.encrypt(m_session_key, m_rng);
125
126 if(session.side() == CLIENT && !session.server_info().empty())
127 m_info_sessions[session.server_info()] = session_id_str;
128 }
129
130}
131
132}
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:143
Session_Manager_In_Memory(RandomNumberGenerator &rng, size_t max_sessions=1000, std::chrono::seconds session_lifetime=std::chrono::seconds(7200))
bool load_from_server_info(const Server_Information &info, Session &session) override
std::chrono::seconds session_lifetime() const override
bool load_from_session_id(const std::vector< uint8_t > &session_id, Session &session) override
void save(const Session &session_data) override
void remove_entry(const std::vector< uint8_t > &session_id) override
const Server_Information & server_info() const
Definition: tls_session.h:183
std::vector< uint8_t > encrypt(const SymmetricKey &key, RandomNumberGenerator &rng) const
std::chrono::system_clock::time_point start_time() const
Definition: tls_session.h:168
Connection_Side side() const
Definition: tls_session.h:134
const std::vector< uint8_t > & session_id() const
Definition: tls_session.h:149
static Session decrypt(const uint8_t ctext[], size_t ctext_size, const SymmetricKey &key)
Definition: alg_id.cpp:13
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:31