Botan 3.11.0
Crypto and TLS for C&
tls_session_manager_stateless.cpp
Go to the documentation of this file.
1/**
2 * TLS Stateless Session Manager for stateless servers
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_stateless.h>
10
11#include <botan/assert.h>
12#include <botan/credentials_manager.h>
13#include <botan/exceptn.h>
14#include <botan/rng.h>
15#include <botan/tls_session.h>
16
17namespace Botan::TLS {
18
19Session_Manager_Stateless::Session_Manager_Stateless(const std::shared_ptr<Credentials_Manager>& creds,
20 const std::shared_ptr<RandomNumberGenerator>& rng) :
21 Session_Manager(rng), m_credentials_manager(creds) {
22 BOTAN_ASSERT_NONNULL(m_credentials_manager);
23}
24
25std::vector<Session_with_Handle> Session_Manager_Stateless::find_some(const Server_Information& /*info*/,
26 size_t /*max_sessions_hint*/) {
27 return {};
28}
29
30std::optional<Session_Handle> Session_Manager_Stateless::establish(const Session& session,
31 const std::optional<Session_ID>& /*session_id*/,
32 bool tls12_no_ticket) {
33 BOTAN_ASSERT(session.side() == Connection_Side::Server, "Client tried to establish a session");
34 if(tls12_no_ticket) {
35 return std::nullopt;
36 }
37
38 const auto key = get_ticket_key();
39 if(!key.has_value()) {
40 return std::nullopt;
41 }
42
43 return Session_Handle(Session_Ticket{session.encrypt(key.value(), *m_rng)});
44}
45
46void Session_Manager_Stateless::store(const Session& /*session*/, const Session_Handle& /*handle*/) {
47 throw Invalid_Argument("A stateless Session Manager cannot store Sessions with their handle");
48}
49
50std::optional<Session> Session_Manager_Stateless::retrieve_one(const Session_Handle& handle) {
51 auto ticket = handle.ticket();
52 if(!ticket.has_value()) {
53 return std::nullopt;
54 }
55
56 const auto key = get_ticket_key();
57 if(!key.has_value()) {
58 return std::nullopt;
59 }
60
61 try {
62 return Session::decrypt(ticket.value(), key.value());
63 } catch(const std::exception&) {
64 // RFC 8446 4.2.11
65 // Any unknown PSKs (e.g., ones not in the PSK database or encrypted
66 // with an unknown key) SHOULD simply be ignored.
67 return std::nullopt;
68 }
69}
70
72 return get_ticket_key().has_value();
73}
74
75std::optional<SymmetricKey> Session_Manager_Stateless::get_ticket_key() noexcept {
76 try {
77 auto key = m_credentials_manager->psk("tls-server", "session-ticket", "");
78 if(key.empty()) {
79 return std::nullopt;
80 }
81 return key;
82 } catch(...) {
83 return std::nullopt;
84 }
85}
86
87} // namespace Botan::TLS
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
Connection_Side side() const
Definition tls_session.h:90
Helper class to embody a session handle in all protocol versions.
std::optional< Session_Ticket > ticket() const
Session_Manager_Stateless(const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< RandomNumberGenerator > &rng)
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).
void store(const Session &session, const Session_Handle &handle) override
Save a Session under a Session_Handle (TLS Client).
std::optional< Session > retrieve_one(const Session_Handle &handle) override
Internal retrieval function for a single session.
BOTAN_FUTURE_EXPLICIT Session_Manager(const std::shared_ptr< RandomNumberGenerator > &rng)
std::shared_ptr< RandomNumberGenerator > m_rng
std::vector< uint8_t > encrypt(const SymmetricKey &key, RandomNumberGenerator &rng) const
static Session decrypt(const uint8_t ctext[], size_t ctext_size, const SymmetricKey &key)
Strong< std::vector< uint8_t >, struct Session_Ticket_ > Session_Ticket
holds a TLS 1.2 session ticket for stateless resumption