Botan 3.11.0
Crypto and TLS for C&
msg_session_ticket_13.cpp
Go to the documentation of this file.
1/*
2* Session Tickets
3* (C) 2021-2022 Jack Lloyd
4* 2021 Elektrobit Automotive GmbH
5* 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/tls_messages_13.h>
11
12#include <botan/tls_callbacks.h>
13#include <botan/tls_exceptn.h>
14#include <botan/tls_extensions_13.h>
15#include <botan/tls_session.h>
16#include <botan/internal/loadstor.h>
17#include <botan/internal/tls_reader.h>
18
19#include <span>
20
21namespace Botan::TLS {
22
23namespace {
24
25template <typename lifetime_t = uint32_t>
26void store_lifetime(std::span<uint8_t> sink, std::chrono::seconds lifetime) {
27 BOTAN_ARG_CHECK(lifetime.count() >= 0 && lifetime.count() <= std::numeric_limits<lifetime_t>::max(),
28 "Ticket lifetime is out of range");
29 store_be(static_cast<lifetime_t>(lifetime.count()), sink.data());
30}
31
32} // namespace
33
35 const Session& session,
37 Callbacks& callbacks) :
38 m_ticket_lifetime_hint(session.lifetime_hint()),
39 m_ticket_age_add(session.session_age_add()),
40 m_ticket_nonce(std::move(nonce)),
41 m_handle(handle.opaque_handle()) {
42 callbacks.tls_modify_extensions(m_extensions, Connection_Side::Server, type());
43}
44
45New_Session_Ticket_13::New_Session_Ticket_13(const std::vector<uint8_t>& buf, Connection_Side from) {
46 TLS_Data_Reader reader("New_Session_Ticket_13", buf);
47
48 m_ticket_lifetime_hint = std::chrono::seconds(reader.get_uint32_t());
49
50 // RFC 8446 4.6.1
51 // Servers MUST NOT use any value [of ticket_lifetime] greater than 604800
52 // seconds (7 days).
53 if(m_ticket_lifetime_hint > std::chrono::days(7)) {
54 throw TLS_Exception(Alert::IllegalParameter, "Received a session ticket with lifetime longer than one week.");
55 }
56
57 m_ticket_age_add = reader.get_uint32_t();
58 m_ticket_nonce = Ticket_Nonce(reader.get_tls_length_value(1));
59 m_handle = Opaque_Session_Handle(reader.get_tls_length_value(2));
60
61 m_extensions.deserialize(reader, from, type());
62
63 // RFC 8446 4.6.1
64 // The sole extension currently defined for NewSessionTicket is
65 // "early_data", indicating that the ticket may be used to send 0-RTT
66 // data [...]. Clients MUST ignore unrecognized extensions.
67 if(m_extensions.contains_implemented_extensions_other_than({Extension_Code::EarlyData})) {
68 throw TLS_Exception(Alert::IllegalParameter, "NewSessionTicket message contained unexpected extension");
69 }
70
71 reader.assert_done();
72}
73
74std::optional<uint32_t> New_Session_Ticket_13::early_data_byte_limit() const {
75 if(!m_extensions.has<EarlyDataIndication>()) {
76 return std::nullopt;
77 }
78
79 const EarlyDataIndication* ext = m_extensions.get<EarlyDataIndication>();
80 BOTAN_ASSERT_NOMSG(ext->max_early_data_size().has_value());
81 return ext->max_early_data_size();
82}
83
84std::vector<uint8_t> New_Session_Ticket_13::serialize() const {
85 std::vector<uint8_t> result(8);
86
87 store_lifetime(std::span(result.data(), 4), m_ticket_lifetime_hint);
88 store_be(m_ticket_age_add, result.data() + 4);
89 append_tls_length_value(result, m_ticket_nonce.get(), 1);
90 append_tls_length_value(result, m_handle.get(), 2);
91
92 // TODO: re-evaluate this construction when reworking message marshalling
93 if(m_extensions.empty()) {
94 result.push_back(0x00);
95 result.push_back(0x00);
96 } else {
97 result += m_extensions.serialize(Connection_Side::Server);
98 }
99
100 return result;
101}
102
103} // namespace Botan::TLS
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
virtual void tls_modify_extensions(Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
std::optional< uint32_t > max_early_data_size() const
Handshake_Type type() const override
std::chrono::seconds lifetime_hint() const
std::optional< uint32_t > early_data_byte_limit() const
const Ticket_Nonce & nonce() const
New_Session_Ticket_13(Ticket_Nonce nonce, const Session &session, const Session_Handle &handle, Callbacks &callbacks)
const Opaque_Session_Handle & handle() const
std::vector< uint8_t > serialize() const override
Helper class to embody a session handle in all protocol versions.
std::vector< uint8_t > get_tls_length_value(size_t len_bytes)
Definition tls_reader.h:105
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition tls_reader.h:177
Strong< std::vector< uint8_t >, struct Ticket_Nonce_ > Ticket_Nonce
Used to derive the ticket's PSK from the resumption_master_secret.
Definition tls_magic.h:96
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...
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:745