Botan  1.11.15
Public Member Functions
Botan::TLS::Session_Manager_SQL Class Reference

#include <tls_session_manager_sql.h>

Inheritance diagram for Botan::TLS::Session_Manager_SQL:
Botan::TLS::Session_Manager Botan::TLS::Session_Manager_SQLite

List of all members.

Public Member Functions

bool load_from_server_info (const Server_Information &info, Session &session) override
bool load_from_session_id (const std::vector< byte > &session_id, Session &session) override
Session_Manager_SQLoperator= (const Session_Manager_SQL &)
void remove_entry (const std::vector< byte > &session_id) override
void save (const Session &session_data) override
std::chrono::seconds session_lifetime () const override
 Session_Manager_SQL (std::shared_ptr< SQL_Database > db, const std::string &passphrase, RandomNumberGenerator &rng, size_t max_sessions=1000, std::chrono::seconds session_lifetime=std::chrono::seconds(7200))
 Session_Manager_SQL (const Session_Manager_SQL &)

Detailed Description

An implementation of Session_Manager that saves values in a SQL database file, with the session data encrypted using a passphrase.

Warning:
For clients, the hostnames associated with the saved sessions are stored in the database in plaintext. This may be a serious privacy risk in some situations.

Definition at line 27 of file tls_session_manager_sql.h.


Constructor & Destructor Documentation

Botan::TLS::Session_Manager_SQL::Session_Manager_SQL ( std::shared_ptr< SQL_Database db,
const std::string &  passphrase,
RandomNumberGenerator rng,
size_t  max_sessions = 1000,
std::chrono::seconds  session_lifetime = std::chrono::seconds(7200) 
)
Parameters:
dbA connection to the database to use The table names botan_tls_sessions and botan_tls_sessions_metadata will be used
passphraseused to encrypt the session data
rnga random number generator
max_sessionsa hint on the maximum number of sessions to keep in memory at any one time. (If zero, don't cap)
session_lifetimesessions are expired after this many seconds have elapsed from initial handshake.

Definition at line 41 of file tls_session_manager_sql.cpp.

References Botan::RandomNumberGenerator::random_vec(), and Botan::unlock().

                                                                            :
   m_db(db),
   m_rng(rng),
   m_max_sessions(max_sessions),
   m_session_lifetime(session_lifetime)
   {
   m_db->create_table(
      "create table if not exists tls_sessions "
      "("
      "session_id TEXT PRIMARY KEY, "
      "session_start INTEGER, "
      "hostname TEXT, "
      "hostport INTEGER, "
      "session BLOB"
      ")");

   m_db->create_table(
      "create table if not exists tls_sessions_metadata "
      "("
      "passphrase_salt BLOB, "
      "passphrase_iterations INTEGER, "
      "passphrase_check INTEGER "
      ")");

   const size_t salts = m_db->row_count("tls_sessions_metadata");

   if(salts == 1)
      {
      // existing db
      auto stmt = m_db->new_statement("select * from tls_sessions_metadata");

      if(stmt->step())
         {
         std::pair<const byte*, size_t> salt = stmt->get_blob(0);
         const size_t iterations = stmt->get_size_t(1);
         const size_t check_val_db = stmt->get_size_t(2);

         size_t check_val_created;
         m_session_key = derive_key(passphrase,
                                    salt.first,
                                    salt.second,
                                    iterations,
                                    check_val_created);

         if(check_val_created != check_val_db)
            throw std::runtime_error("Session database password not valid");
         }
      }
   else
      {
      // maybe just zap the salts + sessions tables in this case?
      if(salts != 0)
         throw std::runtime_error("Seemingly corrupted database, multiple salts found");

      // new database case

      std::vector<byte> salt = unlock(rng.random_vec(16));
      const size_t iterations = 256 * 1024;
      size_t check_val = 0;

      m_session_key = derive_key(passphrase, &salt[0], salt.size(),
                                 iterations, check_val);

      auto stmt = m_db->new_statement("insert into tls_sessions_metadata values(?1, ?2, ?3)");

      stmt->bind(1, salt);
      stmt->bind(2, iterations);
      stmt->bind(3, check_val);

      stmt->spin();
      }
   }

Member Function Documentation

bool Botan::TLS::Session_Manager_SQL::load_from_server_info ( const Server_Information info,
Session session 
) [override, virtual]

Try to load a saved session (using info about server)

Parameters:
infothe information about the server
sessionwill be set to the saved session data (if found), or not modified if not found
Returns:
true if session was modified

Implements Botan::TLS::Session_Manager.

Definition at line 142 of file tls_session_manager_sql.cpp.

References decrypt, Botan::TLS::Server_Information::hostname(), and Botan::TLS::Server_Information::port().

   {
   auto stmt = m_db->new_statement("select session from tls_sessions"
                                   " where hostname = ?1 and hostport = ?2"
                                   " order by session_start desc");

   stmt->bind(1, server.hostname());
   stmt->bind(2, server.port());

   while(stmt->step())
      {
      std::pair<const byte*, size_t> blob = stmt->get_blob(0);

      try
         {
         session = Session::decrypt(blob.first, blob.second, m_session_key);
         return true;
         }
      catch(...)
         {
         }
      }

   return false;
   }
bool Botan::TLS::Session_Manager_SQL::load_from_session_id ( const std::vector< byte > &  session_id,
Session session 
) [override, virtual]

Try to load a saved session (using session ID)

Parameters:
session_idthe session identifier we are trying to resume
sessionwill be set to the saved session data (if found), or not modified if not found
Returns:
true if session was modified

Implements Botan::TLS::Session_Manager.

Definition at line 118 of file tls_session_manager_sql.cpp.

References decrypt, and Botan::hex_encode().

   {
   auto stmt = m_db->new_statement("select session from tls_sessions where session_id = ?1");

   stmt->bind(1, hex_encode(session_id));

   while(stmt->step())
      {
      std::pair<const byte*, size_t> blob = stmt->get_blob(0);

      try
         {
         session = Session::decrypt(blob.first, blob.second, m_session_key);
         return true;
         }
      catch(...)
         {
         }
      }

   return false;
   }
Session_Manager_SQL& Botan::TLS::Session_Manager_SQL::operator= ( const Session_Manager_SQL )
void Botan::TLS::Session_Manager_SQL::remove_entry ( const std::vector< byte > &  session_id) [override, virtual]

Remove this session id from the cache, if it exists

Implements Botan::TLS::Session_Manager.

Definition at line 169 of file tls_session_manager_sql.cpp.

References Botan::hex_encode().

   {
   auto stmt = m_db->new_statement("delete from tls_sessions where session_id = ?1");

   stmt->bind(1, hex_encode(session_id));

   stmt->spin();
   }
void Botan::TLS::Session_Manager_SQL::save ( const Session session) [override, virtual]

Save a session on a best effort basis; the manager may not in fact be able to save the session for whatever reason; this is not an error. Caller cannot assume that calling save followed immediately by load_from_* will result in a successful lookup.

Parameters:
sessionto save

Implements Botan::TLS::Session_Manager.

Definition at line 178 of file tls_session_manager_sql.cpp.

References Botan::TLS::Session::encrypt(), Botan::hex_encode(), Botan::TLS::Server_Information::hostname(), Botan::TLS::Server_Information::port(), Botan::TLS::Session::server_info(), Botan::TLS::Session::session_id(), and Botan::TLS::Session::start_time().

   {
   auto stmt = m_db->new_statement("insert or replace into tls_sessions"
                                   " values(?1, ?2, ?3, ?4, ?5)");

   stmt->bind(1, hex_encode(session.session_id()));
   stmt->bind(2, session.start_time());
   stmt->bind(3, session.server_info().hostname());
   stmt->bind(4, session.server_info().port());
   stmt->bind(5, session.encrypt(m_session_key, m_rng));

   stmt->spin();

   prune_session_cache();
   }
std::chrono::seconds Botan::TLS::Session_Manager_SQL::session_lifetime ( ) const [inline, override, virtual]

Return the allowed lifetime of a session; beyond this time, sessions are not resumed. Returns 0 if unknown/no explicit expiration policy.

Implements Botan::TLS::Session_Manager.

Definition at line 61 of file tls_session_manager_sql.h.

         { return m_session_lifetime; }

The documentation for this class was generated from the following files: