Botan 3.13.0
Crypto and TLS for C&
tls_record_layer_13.h
Go to the documentation of this file.
1/*
2* TLS record layer implementation for TLS 1.3
3* (C) 2022 Jack Lloyd
4* 2022 Hannes Rantzsch, René Meusel - neXenio GmbH
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#ifndef BOTAN_TLS_RECORD_LAYER_13_H_
10#define BOTAN_TLS_RECORD_LAYER_13_H_
11
12#include <botan/secmem.h>
13#include <botan/tls_magic.h>
14#include <memory>
15#include <optional>
16#include <span>
17#include <variant>
18#include <vector>
19
20namespace Botan::TLS {
21
22/**
23 * Resembles the `TLSPlaintext` structure in RFC 8446 5.1
24 * minus the record protocol specifics and ossified bytes.
25 */
26struct Record {
27 Record_Type type; // NOLINT(*non-private-member-variable*)
28 secure_vector<uint8_t> fragment; // NOLINT(*non-private-member-variable*)
29
30 // unprotected records have no sequence number
31 std::optional<uint64_t> seq_no; // NOLINT(*non-private-member-variable*)
32
34 type(record_type), fragment(std::move(frgmnt)), seq_no(std::nullopt) {}
35};
36
37using BytesNeeded = size_t;
38
39class Cipher_State;
40class Policy;
41
42/**
43 * Implementation of the TLS 1.3 record protocol layer
44 *
45 * This component transforms bytes received from the peer into bytes
46 * containing plaintext TLS messages and vice versa.
47 */
49 public:
50 Record_Layer(Connection_Side side, std::shared_ptr<const Policy> policy);
51
52 template <typename ResT>
53 using ReadResult = std::variant<BytesNeeded, ResT>;
54
55 /**
56 * Reads data that was received by the peer and stores it internally for further
57 * processing during the invocation of `next_record()`.
58 *
59 * @param data_from_peer The data to be parsed.
60 */
61 void copy_data(std::span<const uint8_t> data_from_peer);
62
63 /**
64 * Parses one record off the internal buffer that is being filled using `copy_data`.
65 *
66 * Return value contains either the number of bytes (`size_t`) needed to proceed
67 * with processing TLS records or a single plaintext TLS record content containing
68 * higher level protocol or application data.
69 *
70 * @param cipher_state Optional pointer to a Cipher_State instance. If provided, the
71 * cipher_state should be ready to decrypt data. Pass nullptr to
72 * process plaintext data.
73 */
74 ReadResult<Record> next_record(Cipher_State* cipher_state = nullptr);
75
76 std::vector<uint8_t> prepare_records(Record_Type type,
77 std::span<const uint8_t> data,
78 Cipher_State* cipher_state = nullptr) const;
79
80 /**
81 * Clears any data currently stored in the read buffer. This is typically
82 * used for memory cleanup when the peer sent a CloseNotify alert.
83 */
85 zap(m_read_buffer);
86 m_read_offset = 0;
87 }
88
89 /**
90 * Set the record size limits as negotiated by the "record_size_limit"
91 * extension (RFC 8449). The limits refer to the number of plaintext bytes
92 * to be encrypted/decrypted -- INCLUDING the encrypted content type byte
93 * introduced with TLS 1.3. The record size limit is _not_ applied to
94 * unprotected records. Incoming records that exceed the set limit will
95 * result in a fatal alert.
96 *
97 * @param outgoing_limit the maximal number of plaintext bytes to be
98 * sent in a protected record
99 * @param incoming_limit the maximal number of plaintext bytes to be
100 * accepted in a received protected record
101 */
102 void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit);
103
104 void disable_sending_compat_mode() { m_sending_compat_mode = false; }
105
106 void disable_receiving_compat_mode() { m_receiving_compat_mode = false; }
107
108 private:
109 std::vector<uint8_t> m_read_buffer;
110 size_t m_read_offset = 0;
111 Connection_Side m_side;
112
113 // Queried for Record Padding as defined in RFC 9846 5.4
114 std::shared_ptr<const Policy> m_policy;
115
116 // Those are either the limits set by the TLS 1.3 specification (RFC 8446),
117 // or the ones negotiated via the "record_size_limit" extension (RFC 8449).
118 uint16_t m_outgoing_record_size_limit;
119 uint16_t m_incoming_record_size_limit;
120
121 // Those status flags are required for version validation where the initial
122 // records for sending and receiving is handled differently for backward
123 // compatibility reasons. (RFC 8446 5.1 regarding "legacy_record_version")
124 bool m_sending_compat_mode;
125 bool m_receiving_compat_mode;
126};
127
128} // namespace Botan::TLS
129
130#endif
#define BOTAN_TEST_API
Definition api.h:41
std::variant< BytesNeeded, ResT > ReadResult
void copy_data(std::span< const uint8_t > data_from_peer)
Record_Layer(Connection_Side side, std::shared_ptr< const Policy > policy)
std::vector< uint8_t > prepare_records(Record_Type type, std::span< const uint8_t > data, Cipher_State *cipher_state=nullptr) const
ReadResult< Record > next_record(Cipher_State *cipher_state=nullptr)
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:261
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
std::optional< uint64_t > seq_no
secure_vector< uint8_t > fragment
Record(Record_Type record_type, secure_vector< uint8_t > frgmnt)