/** * TLS Stateless Session Manager for stateless servers * (C) 2023 Jack Lloyd * 2023 René Meusel - Rohde & Schwarz Cybersecurity * * Botan is released under the Simplified BSD License (see license.txt) */ #include #include #include #include #include namespace Botan::TLS { Session_Manager_Stateless::Session_Manager_Stateless(const std::shared_ptr& creds, const std::shared_ptr& rng) : Session_Manager(rng), m_credentials_manager(creds) { BOTAN_ASSERT_NONNULL(m_credentials_manager); } std::optional Session_Manager_Stateless::establish(const Session& session, const std::optional&, bool tls12_no_ticket) { BOTAN_ASSERT(session.side() == Connection_Side::Server, "Client tried to establish a session"); if(tls12_no_ticket) { return std::nullopt; } const auto key = get_ticket_key(); if(!key.has_value()) { return std::nullopt; } return Session_Ticket{session.encrypt(key.value(), *m_rng)}; } void Session_Manager_Stateless::store(const Session&, const Session_Handle&) { throw Invalid_Argument("A stateless Session Manager cannot store Sessions with their handle"); } std::optional Session_Manager_Stateless::retrieve_one(const Session_Handle& handle) { auto ticket = handle.ticket(); if(!ticket.has_value()) { return std::nullopt; } const auto key = get_ticket_key(); if(!key.has_value()) { return std::nullopt; } try { return Session::decrypt(ticket.value(), key.value()); } catch(const std::exception&) { // RFC 8446 4.2.11 // Any unknown PSKs (e.g., ones not in the PSK database or encrypted // with an unknown key) SHOULD simply be ignored. return std::nullopt; } } bool Session_Manager_Stateless::emits_session_tickets() { return get_ticket_key().has_value(); } std::optional Session_Manager_Stateless::get_ticket_key() noexcept { try { auto key = m_credentials_manager->psk("tls-server", "session-ticket", ""); if(key.empty()) { return std::nullopt; } return key; } catch(...) { return std::nullopt; } } } // namespace Botan::TLS