Botan 3.11.0
Crypto and TLS for C&
tls_session_manager_hybrid.cpp
Go to the documentation of this file.
1/**
2 * Hybrid Session Manager that emits both IDs and Tickets
3 * (C) 2023 Jack Lloyd
4 * 2023 René Meusel - Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9#include <botan/tls_session_manager_hybrid.h>
10
11#include <botan/assert.h>
12#include <botan/tls_session.h>
13#include <functional>
14
15namespace Botan::TLS {
16
17Session_Manager_Hybrid::Session_Manager_Hybrid(std::unique_ptr<Session_Manager> stateful,
18 const std::shared_ptr<Credentials_Manager>& credentials_manager,
19 const std::shared_ptr<RandomNumberGenerator>& rng,
20 bool prefer_tickets) :
21 Session_Manager(rng),
22 m_stateful(std::move(stateful)),
23 m_stateless(credentials_manager, rng),
24 m_prefer_tickets(prefer_tickets) {
25 BOTAN_ASSERT_NONNULL(m_stateful);
26}
27
28std::vector<Session_with_Handle> Session_Manager_Hybrid::find(const Server_Information& info,
29 Callbacks& callbacks,
30 const Policy& policy) {
31 return m_stateful->find(info, callbacks, policy);
32}
33
34std::optional<Session_Handle> Session_Manager_Hybrid::establish(const Session& session,
35 const std::optional<Session_ID>& id,
36 bool tls12_no_ticket) {
37 auto create_ticket = [&]() -> std::optional<Session_Handle> {
38 if(tls12_no_ticket) {
39 return std::nullopt;
40 }
41
42 auto ticket_handle = m_stateless.establish(session, id, false /* always allow tickets */);
43 BOTAN_ASSERT_IMPLICATION(ticket_handle.has_value(),
44 ticket_handle->is_ticket(),
45 "Session_Manager_Stateless produced unexpected Session_Handle");
46 return ticket_handle;
47 };
48
49 auto create_id = [&] {
50 // If we're dealing with a TLS 1.2 connection, we opportunistically
51 // disable tickets for the underlying manager.
52 auto id_handle = m_stateful->establish(session, id, session.version().is_pre_tls_13());
54 id_handle.has_value(), id_handle->is_id(), "Session_Manager_In_Memory produced unexpected Session_Handle");
55 return id_handle;
56 };
57
58 std::function preferred = create_ticket;
59 std::function fallback = create_id;
60
61 if(!m_prefer_tickets) {
62 std::swap(preferred, fallback);
63 }
64
65 if(auto result = preferred()) {
66 return result;
67 }
68
69 return fallback();
70}
71
72std::optional<Session> Session_Manager_Hybrid::retrieve(const Session_Handle& handle,
73 Callbacks& callbacks,
74 const Policy& policy) {
75 std::reference_wrapper<Session_Manager> preferred = m_stateless;
76 std::reference_wrapper<Session_Manager> fallback = *m_stateful;
77
78 if(!m_prefer_tickets) {
79 std::swap(preferred, fallback);
80 }
81
82 if(auto session = preferred.get().retrieve(handle, callbacks, policy)) {
83 return session;
84 }
85
86 return fallback.get().retrieve(handle, callbacks, policy);
87}
88
90 return m_stateless.emits_session_tickets() || m_stateful->emits_session_tickets();
91}
92
93std::optional<Session> Session_Manager_Hybrid::retrieve_one(const Session_Handle& /*handle*/) {
94 BOTAN_ASSERT(false, "This should never be called");
95}
96
97std::vector<Session_with_Handle> Session_Manager_Hybrid::find_some(const Server_Information& /*info*/,
98 size_t /*max_sessions_hint*/) {
99 BOTAN_ASSERT(false, "This should never be called");
100}
101
102} // namespace Botan::TLS
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
Definition assert.h:101
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
Protocol_Version version() const
Definition tls_session.h:75
Helper class to embody a session handle in all protocol versions.
std::optional< Session > retrieve(const Session_Handle &handle, Callbacks &callbacks, const Policy &policy) override
Retrieves a specific session given a handle.
std::optional< Session > retrieve_one(const Session_Handle &handle) override
Internal retrieval function for a single session.
Session_Manager_Hybrid(std::unique_ptr< Session_Manager > stateful_manager, const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< RandomNumberGenerator > &rng, bool prefer_tickets=true)
std::vector< Session_with_Handle > find(const Server_Information &info, Callbacks &callbacks, const Policy &policy) override
Find all sessions that match a given server info.
std::vector< Session_with_Handle > find_some(const Server_Information &info, size_t max_sessions_hint) override
Internal retrieval function to find sessions to resume.
std::optional< Session_Handle > establish(const Session &session, const std::optional< Session_ID > &id=std::nullopt, bool tls12_no_ticket=false) override
Save a new Session and assign a Session_Handle (TLS Server).
BOTAN_FUTURE_EXPLICIT Session_Manager(const std::shared_ptr< RandomNumberGenerator > &rng)