9#include <botan/tls_session_manager.h>
11#include <botan/assert.h>
13#include <botan/tls_callbacks.h>
14#include <botan/tls_policy.h>
15#include <botan/tls_session.h>
18#if defined(BOTAN_HAS_TLS_13)
19 #include <botan/tls_psk_identity_13.h>
29 const std::optional<Session_ID>&
id,
30 bool tls12_no_ticket) {
39 store(session, handle);
51 if(!session.has_value()) {
56 const std::chrono::seconds policy_lifetime =
77 const auto ticket_age =
78 std::chrono::duration_cast<std::chrono::seconds>(callbacks.
tls_current_timestamp() - session->start_time());
79 const bool expired = ticket_age > policy_lifetime;
89std::vector<Session_with_Handle> Session_Manager::find_and_filter(
const Server_Information& info,
94 const std::chrono::seconds policy_lifetime =
102 constexpr unsigned int max_attempts = 10;
103 std::vector<Session_with_Handle> sessions_and_handles;
107 for(
unsigned int attempt = 0; attempt < max_attempts && sessions_and_handles.empty(); ++attempt) {
108 sessions_and_handles =
find_some(info, max_sessions_hint);
111 if(sessions_and_handles.empty()) {
115 std::erase_if(sessions_and_handles, [&](
const auto& session) {
116 const auto age = std::chrono::duration_cast<std::chrono::seconds>(now - session.session.start_time());
148 const auto session_lifetime_hint = session.session.lifetime_hint();
149 const bool expired = age > std::min(policy_lifetime, session_lifetime_hint);
159 return sessions_and_handles;
171 std::optional<lock_guard_type<recursive_mutex_type>> lk;
172 if(!allow_reusing_tickets) {
176 auto sessions_and_handles = find_and_filter(info, callbacks, policy);
181 while(session_limit > 0 && sessions_and_handles.size() > session_limit) {
182 sessions_and_handles.pop_back();
191 if(!allow_reusing_tickets) {
195 for(
const auto& [session, handle] : sessions_and_handles) {
196 if(!session.version().is_pre_tls_13() || !handle.is_id()) {
202 return sessions_and_handles;
205#if defined(BOTAN_HAS_TLS_13)
208 const std::vector<PskIdentity>& tickets,
209 std::string_view hash_function,
215 for(uint16_t i = 0;
const auto& ticket : tickets) {
217 if(session.has_value() && session->ciphersuite().prf_algo() == hash_function &&
218 session->version().is_tls_13_or_later()) {
219 return std::pair{std::move(session.value()), i};
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
#define BOTAN_ASSERT(expr, assertion_made)
virtual std::chrono::system_clock::time_point tls_current_timestamp()
virtual bool reuse_session_tickets() const
virtual size_t maximum_session_tickets_per_client_hello() const
virtual std::chrono::seconds session_ticket_lifetime() const
Connection_Side side() const
Helper class to embody a session handle in all protocol versions.
virtual std::optional< std::pair< Session, uint16_t > > choose_from_offered_tickets(const std::vector< PskIdentity > &tickets, std::string_view hash_function, Callbacks &callbacks, const Policy &policy)
virtual size_t remove(const Session_Handle &handle)=0
virtual std::optional< Session > retrieve_one(const Session_Handle &handle)=0
Internal retrieval function for a single session.
virtual void store(const Session &session, const Session_Handle &handle)=0
Save a Session under a Session_Handle (TLS Client).
recursive_mutex_type & mutex()
BOTAN_FUTURE_EXPLICIT Session_Manager(const std::shared_ptr< RandomNumberGenerator > &rng)
virtual std::vector< Session_with_Handle > find_some(const Server_Information &info, size_t max_sessions_hint)=0
Internal retrieval function to find sessions to resume.
virtual std::optional< Session_Handle > establish(const Session &session, const std::optional< Session_ID > &id=std::nullopt, bool tls12_no_ticket=false)
Save a new Session and assign a Session_Handle (TLS Server).
virtual std::vector< Session_with_Handle > find(const Server_Information &info, Callbacks &callbacks, const Policy &policy)
Find all sessions that match a given server info.
std::shared_ptr< RandomNumberGenerator > m_rng
virtual std::optional< Session > retrieve(const Session_Handle &handle, Callbacks &callbacks, const Policy &policy)
Retrieves a specific session given a handle.
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption
Strong< std::vector< uint8_t >, struct Opaque_Session_Handle_ > Opaque_Session_Handle
holds an opaque session handle as used in TLS 1.3 that could be either a ticket for stateless resumpt...