Botan 3.10.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
16namespace Botan::TLS {
17
18Session_Manager_Stateless::Session_Manager_Stateless(const std::shared_ptr<Credentials_Manager>& creds,
19 const std::shared_ptr<RandomNumberGenerator>& rng) :
20 Session_Manager(rng), m_credentials_manager(creds) {
21 BOTAN_ASSERT_NONNULL(m_credentials_manager);
22}
23
24std::optional<Session_Handle> Session_Manager_Stateless::establish(const Session& session,
25 const std::optional<Session_ID>& /*session_id*/,
26 bool tls12_no_ticket) {
27 BOTAN_ASSERT(session.side() == Connection_Side::Server, "Client tried to establish a session");
28 if(tls12_no_ticket) {
29 return std::nullopt;
30 }
31
32 const auto key = get_ticket_key();
33 if(!key.has_value()) {
34 return std::nullopt;
35 }
36
37 return Session_Handle(Session_Ticket{session.encrypt(key.value(), *m_rng)});
38}
39
40void Session_Manager_Stateless::store(const Session& /*session*/, const Session_Handle& /*handle*/) {
41 throw Invalid_Argument("A stateless Session Manager cannot store Sessions with their handle");
42}
43
44std::optional<Session> Session_Manager_Stateless::retrieve_one(const Session_Handle& handle) {
45 auto ticket = handle.ticket();
46 if(!ticket.has_value()) {
47 return std::nullopt;
48 }
49
50 const auto key = get_ticket_key();
51 if(!key.has_value()) {
52 return std::nullopt;
53 }
54
55 try {
56 return Session::decrypt(ticket.value(), key.value());
57 } catch(const std::exception&) {
58 // RFC 8446 4.2.11
59 // Any unknown PSKs (e.g., ones not in the PSK database or encrypted
60 // with an unknown key) SHOULD simply be ignored.
61 return std::nullopt;
62 }
63}
64
66 return get_ticket_key().has_value();
67}
68
69std::optional<SymmetricKey> Session_Manager_Stateless::get_ticket_key() noexcept {
70 try {
71 auto key = m_credentials_manager->psk("tls-server", "session-ticket", "");
72 if(key.empty()) {
73 return std::nullopt;
74 }
75 return key;
76 } catch(...) {
77 return std::nullopt;
78 }
79}
80
81} // 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
Helper class to embody a session handle in all protocol versions.
Definition tls_session.h:63
std::optional< Session_Ticket > ticket() const
Session_Manager_Stateless(const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< RandomNumberGenerator > &rng)
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
Definition tls_session.h:34