• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 25139258422

29 Apr 2026 08:02PM UTC coverage: 89.37% (-0.02%) from 89.385%
25139258422

push

github

web-flow
Merge pull request #5550 from randombit/jack/tls-misc

TLS conformance, hardening, and performance fixes

107055 of 119789 relevant lines covered (89.37%)

11415549.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.02
/src/lib/tls/tls13/msg_session_ticket_13.cpp
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

21
namespace Botan::TLS {
22

23
namespace {
24

25
template <typename lifetime_t = uint32_t>
26
void store_lifetime(std::span<uint8_t> sink, std::chrono::seconds lifetime) {
293✔
27
   BOTAN_ARG_CHECK(lifetime.count() >= 0 && lifetime.count() <= std::numeric_limits<lifetime_t>::max(),
293✔
28
                   "Ticket lifetime is out of range");
29
   store_be(static_cast<lifetime_t>(lifetime.count()), sink.data());
293✔
30
}
293✔
31

32
}  // namespace
33

34
New_Session_Ticket_13::New_Session_Ticket_13(Ticket_Nonce nonce,
292✔
35
                                             const Session& session,
36
                                             const Session_Handle& handle,
37
                                             Callbacks& callbacks) :
292✔
38
      m_ticket_lifetime_hint(session.lifetime_hint()),
292✔
39
      m_ticket_age_add(session.session_age_add()),
292✔
40
      m_ticket_nonce(std::move(nonce)),
292✔
41
      m_handle(handle.opaque_handle()) {
292✔
42
   callbacks.tls_modify_extensions(m_extensions, Connection_Side::Server, type());
292✔
43
}
292✔
44

45
New_Session_Ticket_13::New_Session_Ticket_13(const std::vector<uint8_t>& buf, Connection_Side from) {
659✔
46
   TLS_Data_Reader reader("New_Session_Ticket_13", buf);
659✔
47

48
   m_ticket_lifetime_hint = std::chrono::seconds(reader.get_uint32_t());
659✔
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)) {
659✔
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();
659✔
58
   m_ticket_nonce = Ticket_Nonce(reader.get_tls_length_value(1));
1,318✔
59
   // RFC 8446 4.6.1: opaque ticket<1..2^16-1>
60
   m_handle = Opaque_Session_Handle(reader.get_range<uint8_t>(2, 1, 65535));
659✔
61

62
   m_extensions.deserialize(reader, from, type());
659✔
63

64
   // RFC 8446 4.6.1
65
   //    The sole extension currently defined for NewSessionTicket is
66
   //    "early_data", indicating that the ticket may be used to send 0-RTT
67
   //    data [...]. Clients MUST ignore unrecognized extensions.
68
   if(m_extensions.contains_implemented_extensions_other_than({Extension_Code::EarlyData})) {
1,318✔
69
      throw TLS_Exception(Alert::IllegalParameter, "NewSessionTicket message contained unexpected extension");
×
70
   }
71

72
   reader.assert_done();
659✔
73
}
659✔
74

75
std::optional<uint32_t> New_Session_Ticket_13::early_data_byte_limit() const {
659✔
76
   if(!m_extensions.has<EarlyDataIndication>()) {
659✔
77
      return std::nullopt;
658✔
78
   }
79

80
   const EarlyDataIndication* ext = m_extensions.get<EarlyDataIndication>();
1✔
81
   BOTAN_ASSERT_NOMSG(ext->max_early_data_size().has_value());
1✔
82
   return ext->max_early_data_size();
1✔
83
}
84

85
std::vector<uint8_t> New_Session_Ticket_13::serialize() const {
293✔
86
   std::vector<uint8_t> result(8);
293✔
87

88
   store_lifetime(std::span(result.data(), 4), m_ticket_lifetime_hint);
293✔
89
   store_be(m_ticket_age_add, result.data() + 4);
293✔
90
   append_tls_length_value(result, m_ticket_nonce.get(), 1);
293✔
91
   append_tls_length_value(result, m_handle.get(), 2);
293✔
92

93
   // TODO: re-evaluate this construction when reworking message marshalling
94
   if(m_extensions.empty()) {
293✔
95
      result.push_back(0x00);
291✔
96
      result.push_back(0x00);
291✔
97
   } else {
98
      result += m_extensions.serialize(Connection_Side::Server);
4✔
99
   }
100

101
   return result;
293✔
102
}
×
103

104
}  // namespace Botan::TLS
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc