Botan 3.9.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 <optional>
13#include <span>
14#include <variant>
15#include <vector>
16
17#include <botan/secmem.h>
18#include <botan/tls_magic.h>
19#include <botan/internal/tls_channel_impl.h>
20
21namespace Botan::TLS {
22
23/**
24 * Resembles the `TLSPlaintext` structure in RFC 8446 5.1
25 * minus the record protocol specifics and ossified bytes.
26 */
27struct Record {
28 Record_Type type; // NOLINT(*non-private-member-variable*)
29 secure_vector<uint8_t> fragment; // NOLINT(*non-private-member-variable*)
30
31 // unprotected records have no sequence number
32 std::optional<uint64_t> seq_no; // NOLINT(*non-private-member-variable*)
33
35 type(record_type), fragment(std::move(frgmnt)), seq_no(std::nullopt) {}
36};
37
38using BytesNeeded = size_t;
39
40class Cipher_State;
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 explicit Record_Layer(Connection_Side side);
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 */
84 void clear_read_buffer() { zap(m_read_buffer); }
85
86 /**
87 * Set the record size limits as negotiated by the "record_size_limit"
88 * extension (RFC 8449). The limits refer to the number of plaintext bytes
89 * to be encrypted/decrypted -- INCLUDING the encrypted content type byte
90 * introduced with TLS 1.3. The record size limit is _not_ applied to
91 * unprotected records. Incoming records that exceed the set limit will
92 * result in a fatal alert.
93 *
94 * @param outgoing_limit the maximal number of plaintext bytes to be
95 * sent in a protected record
96 * @param incoming_limit the maximal number of plaintext bytes to be
97 * accepted in a received protected record
98 */
99 void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit);
100
101 void disable_sending_compat_mode() { m_sending_compat_mode = false; }
102
103 void disable_receiving_compat_mode() { m_receiving_compat_mode = false; }
104
105 private:
106 std::vector<uint8_t> m_read_buffer;
107 Connection_Side m_side;
108
109 // Those are either the limits set by the TLS 1.3 specification (RFC 8446),
110 // or the ones negotiated via the "record_size_limit" extension (RFC 8449).
111 uint16_t m_outgoing_record_size_limit;
112 uint16_t m_incoming_record_size_limit;
113
114 // Those status flags are required for version validation where the initial
115 // records for sending and receiving is handled differently for backward
116 // compatibility reasons. (RFC 8446 5.1 regarding "legacy_record_version")
117 bool m_sending_compat_mode;
118 bool m_receiving_compat_mode;
119};
120
121} // namespace Botan::TLS
122
123#endif
#define BOTAN_TEST_API
Definition api.h:41
std::variant< BytesNeeded, ResT > ReadResult
Record_Layer(Connection_Side side)
void copy_data(std::span< const uint8_t > data_from_peer)
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:134
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:69
std::optional< uint64_t > seq_no
secure_vector< uint8_t > fragment
Record(Record_Type record_type, secure_vector< uint8_t > frgmnt)