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