Botan 3.11.0
Crypto and TLS for C&
tls_session_id.h
Go to the documentation of this file.
1/*
2* (C) 2022 René Meusel - Rohde & Schwarz Cybersecurity
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#ifndef BOTAN_TLS_SESSION_ID_H_
8#define BOTAN_TLS_SESSION_ID_H_
9
10#include <botan/strong_type.h>
11#include <botan/types.h>
12#include <optional>
13#include <variant>
14#include <vector>
15
16namespace Botan::TLS {
17
18// Different flavors of session handles are used, depending on the usage
19// scenario and the TLS protocol version.
20
21/// @brief holds a TLS 1.2 session ID for stateful resumption
22using Session_ID = Strong<std::vector<uint8_t>, struct Session_ID_>;
23
24/// @brief holds a TLS 1.2 session ticket for stateless resumption
25using Session_Ticket = Strong<std::vector<uint8_t>, struct Session_Ticket_>;
26
27/// @brief holds an opaque session handle as used in TLS 1.3 that could be
28/// either a ticket for stateless resumption or a database handle.
29using Opaque_Session_Handle = Strong<std::vector<uint8_t>, struct Opaque_Session_Handle_>;
30
31inline auto operator<(const Session_ID& id1, const Session_ID& id2) {
32 return id1.get() < id2.get();
33}
34
35/**
36 * @brief Helper class to embody a session handle in all protocol versions
37 *
38 * Sessions in TLS 1.2 are identified by an arbitrary and unique ID of up to
39 * 32 bytes or by a self-contained arbitrary-length ticket (RFC 5077).
40 *
41 * TLS 1.3 does not distinct between the two and handles both as tickets. Also
42 * a TLS 1.3 server can issue multiple tickets in one connection and the
43 * resumption mechanism is compatible with the PSK establishment.
44 *
45 * Concrete implementations of Session_Manager use this helper to distinguish
46 * the different states and manage sessions for TLS 1.2 and 1.3 connections.
47 *
48 * Note that all information stored in a Session_Handle might be transmitted in
49 * unprotected form. Hence, it should not contain any confidential information.
50 */
52 public:
53 // NOLINTBEGIN(*-explicit-conversions)
54
55 /**
56 * Constructs a Session_Handle from a session ID which is an
57 * arbitrary byte vector that must be 32 bytes long at most.
58 */
59 Session_Handle(Session_ID id) : m_handle(std::move(id)) { validate_constraints(); }
60
61 /**
62 * Constructs a Session_Handle from a session ticket which is a
63 * non-empty byte vector that must be 64kB long at most.
64 * Typically, tickets facilitate stateless server implementations
65 * and contain all relevant context in encrypted/authenticated form.
66 *
67 * Note that (for technical reasons) we enforce that tickets are
68 * longer than 32 bytes.
69 */
70 Session_Handle(Session_Ticket ticket) : m_handle(std::move(ticket)) { validate_constraints(); }
71
72 /**
73 * Constructs a Session_Handle from an Opaque_Handle such as TLS 1.3
74 * uses them in its resumption mechanism. This could be either a
75 * Session_ID or a Session_Ticket and it is up to the Session_Manager
76 * to figure out what it actually is.
77 */
78 Session_Handle(Opaque_Session_Handle ticket) : m_handle(std::move(ticket)) { validate_constraints(); }
79
80 // NOLINTEND(*-explicit-conversions)
81
82 bool is_id() const { return std::holds_alternative<Session_ID>(m_handle); }
83
84 bool is_ticket() const { return std::holds_alternative<Session_Ticket>(m_handle); }
85
86 bool is_opaque_handle() const { return std::holds_alternative<Opaque_Session_Handle>(m_handle); }
87
88 /**
89 * Returns the Session_Handle as an opaque handle. If the object was not
90 * constructed as an Opaque_Session_Handle, the contained value is
91 * converted.
92 */
93 Opaque_Session_Handle opaque_handle() const;
94
95 /**
96 * If the Session_Handle was constructed with a Session_ID or an
97 * Opaque_Session_Handle that can be converted to a Session_ID (up to
98 * 32 bytes long), this returns the handle as a Session_ID. Otherwise,
99 * std::nullopt is returned.
100 */
101 std::optional<Session_ID> id() const;
102
103 /**
104 * If the Session_Handle was constructed with a Session_Ticket or an
105 * Opaque_Session_Handle this returns the handle as a Session_ID.
106 * Otherwise, std::nullopt is returned.
107 */
108 std::optional<Session_Ticket> ticket() const;
109
110 decltype(auto) get() const { return m_handle; }
111
112 private:
113 void validate_constraints() const;
114
115 private:
116 std::variant<Session_ID, Session_Ticket, Opaque_Session_Handle> m_handle;
117};
118
119} // namespace Botan::TLS
120
121#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
std::optional< Session_Ticket > ticket() const
decltype(auto) get() const
Session_Handle(Session_Ticket ticket)
Session_Handle(Opaque_Session_Handle ticket)
std::optional< Session_ID > id() const
constexpr T & get() &
Definition strong_type.h:85
bool operator<(const Server_Information &a, const Server_Information &b)
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption
Strong< std::vector< uint8_t >, struct Session_Ticket_ > Session_Ticket
holds a TLS 1.2 session ticket for stateless resumption
Strong< std::vector< uint8_t >, struct Opaque_Session_Handle_ > Opaque_Session_Handle
holds an opaque session handle as used in TLS 1.3 that could be either a ticket for stateless resumpt...