Botan 3.9.0
Crypto and TLS for C&
tls_channel_impl.h
Go to the documentation of this file.
1/*
2* TLS Channel
3* (C) 2011,2012,2014,2015 Jack Lloyd
4* 2016 Matthias Gierlings
5* 2021 Elektrobit Automotive GmbH
6* 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#ifndef BOTAN_TLS_CHANNEL_IMPL_H_
12#define BOTAN_TLS_CHANNEL_IMPL_H_
13
14#include <botan/assert.h>
15#include <botan/tls_channel.h>
16#include <botan/tls_magic.h>
17#include <botan/tls_version.h>
18
19#include <memory>
20#include <utility>
21#include <vector>
22
23namespace Botan {
24
27
28namespace TLS {
29
30class Client;
31class Server;
32
33enum class Record_Type : uint8_t {
34 Invalid = 0, // RFC 8446 (TLS 1.3)
35
37 Alert = 21,
40
41 Heartbeat = 24, // RFC 6520 (TLS 1.3)
42};
43
45 public:
46 virtual ~Channel_Impl() = default;
47
48 Channel_Impl(const Channel_Impl& other) = delete;
49 Channel_Impl(Channel_Impl&& other) = default;
50 Channel_Impl& operator=(const Channel_Impl& other) = delete;
52
53 /**
54 * Inject TLS traffic received from counterparty
55 * @return a hint as the how many more bytes we need to q the
56 * current record (this may be 0 if on a record boundary)
57 */
58 virtual size_t from_peer(std::span<const uint8_t> data) = 0;
59
60 /**
61 * Inject plaintext intended for counterparty
62 * Throws an exception if is_active() is false
63 */
64 virtual void to_peer(std::span<const uint8_t> data) = 0;
65
66 /**
67 * Send a TLS alert message. If the alert is fatal, the internal
68 * state (keys, etc) will be reset.
69 * @param alert the Alert to send
70 */
71 virtual void send_alert(const Alert& alert) = 0;
72
73 /**
74 * Send a warning alert
75 */
76 void send_warning_alert(Alert::Type type) { send_alert(Alert(type, false)); }
77
78 /**
79 * Send a fatal alert
80 */
81 void send_fatal_alert(Alert::Type type) { send_alert(Alert(type, true)); }
82
83 /**
84 * Send a close notification alert
85 */
86 void close() { send_warning_alert(Alert::CloseNotify); }
87
88 /**
89 * @return true iff the TLS handshake has finished successfully
90 */
91 virtual bool is_handshake_complete() const = 0;
92
93 /**
94 * @return true iff the connection is active for sending application data
95 */
96 virtual bool is_active() const = 0;
97
98 /**
99 * @return true iff the connection has been definitely closed
100 */
101 virtual bool is_closed() const = 0;
102
103 /**
104 * @return true iff the connection is active for sending application data
105 */
106 virtual bool is_closed_for_reading() const = 0;
107
108 /**
109 * @return true iff the connection has been definitely closed
110 */
111 virtual bool is_closed_for_writing() const = 0;
112
113 /**
114 * @return certificate chain of the peer (may be empty)
115 */
116 virtual std::vector<X509_Certificate> peer_cert_chain() const = 0;
117
118 /**
119 * @return raw public key of the peer (may be nullptr)
120 */
121 virtual std::shared_ptr<const Public_Key> peer_raw_public_key() const = 0;
122
123 /**
124 * @return identity of the PSK used for this connection
125 * or std::nullopt if no PSK was used.
126 */
127 virtual std::optional<std::string> external_psk_identity() const = 0;
128
129 /**
130 * Key material export (RFC 5705)
131 * @param label a disambiguating label string
132 * @param context a per-association context value
133 * @param length the length of the desired key in bytes
134 * @return key of length bytes
135 */
136 virtual SymmetricKey key_material_export(std::string_view label,
137 std::string_view context,
138 size_t length) const = 0;
139
140 /**
141 * Attempt to renegotiate the session
142 * @param force_full_renegotiation if true, require a full renegotiation,
143 * otherwise allow session resumption
144 */
145 virtual void renegotiate(bool force_full_renegotiation = false) = 0;
146
147 /**
148 * @return true if this channel can issue TLS 1.3 style session tickets.
149 */
150 virtual bool new_session_ticket_supported() const { return false; }
151
152 /**
153 * Send @p tickets new session tickets to the peer. This is only supported
154 * on TLS 1.3 servers.
155 *
156 * If the server's Session_Manager does not accept the generated Session
157 * objects, the server implementation won't be able to send new tickets.
158 * Additionally, anything but TLS 1.3 servers will return 0 (because they
159 * don't support sending such session tickets).
160 *
161 * @returns the number of session tickets successfully sent to the client
162 */
163 virtual size_t send_new_session_tickets(const size_t /* tickets */) { return 0; }
164
165 /**
166 * Attempt to update the session's traffic key material
167 * Note that this is possible with a TLS 1.3 channel, only.
168 *
169 * @param request_peer_update if true, require a reciprocal key update
170 */
171 virtual void update_traffic_keys(bool request_peer_update = false) = 0;
172
173 /**
174 * @return true iff the counterparty supports the secure
175 * renegotiation extensions.
176 */
177 virtual bool secure_renegotiation_supported() const = 0;
178
179 /**
180 * Perform a handshake timeout check. This does nothing unless
181 * this is a DTLS channel with a pending handshake state, in
182 * which case we check for timeout and potentially retransmit
183 * handshake packets.
184 */
185 virtual bool timeout_check() = 0;
186
187 /**
188 * Return the protocol notification set for this connection, if any (ALPN).
189 * This value is not tied to the session and a later renegotiation of the
190 * same session can choose a new protocol.
191 */
192 virtual std::string application_protocol() const = 0;
193
194 protected:
195 Channel_Impl() = default;
196
197 /**
198 * This struct collect all information required to perform a downgrade from TLS 1.3 to TLS 1.2.
199 *
200 * The downgrade process is (currently) triggered when a TLS 1.3 client receives a downgrade request
201 * in the server hello message (@sa `Client_Impl_13::handle(Server_Hello_12)`). As a result,
202 * `Client::received_data` should detect this condition and replace its `Channel_Impl_13` member by a
203 * `Channel_Impl_12`.
204 *
205 * Note that the downgrade process for the server implementation will likely differ.
206 */
208 /// The client hello message including the handshake header bytes as transferred to the peer.
209 std::vector<uint8_t> client_hello_message;
210
211 /// The full data transcript received from the peer. This will contain the server hello message that forced us to downgrade.
212 std::vector<uint8_t> peer_transcript;
213
214 /// The TLS 1.2 session information found by a TLS 1.3 client that
215 /// caused it to initiate a downgrade before even sending a client hello.
216 std::optional<Session_with_Handle> tls12_session;
217
219 std::vector<std::string> next_protocols;
221
222 std::shared_ptr<Callbacks> callbacks;
223 std::shared_ptr<Session_Manager> session_manager;
224 std::shared_ptr<Credentials_Manager> creds;
225 std::shared_ptr<RandomNumberGenerator> rng;
226 std::shared_ptr<const Policy> policy;
227
230 };
231
232 std::unique_ptr<Downgrade_Information> m_downgrade_info; // NOLINT(*non-private-member-variable*)
233
234 void preserve_peer_transcript(std::span<const uint8_t> input) {
236 m_downgrade_info->peer_transcript.insert(m_downgrade_info->peer_transcript.end(), input.begin(), input.end());
237 }
238
239 void preserve_client_hello(std::span<const uint8_t> msg) {
241 m_downgrade_info->client_hello_message.assign(msg.begin(), msg.end());
242 }
243
244 friend class Client;
245 friend class Server;
246
247 void set_io_buffer_size(size_t io_buf_sz) {
249 m_downgrade_info->io_buffer_size = io_buf_sz;
250 }
251
252 /**
253 * Implementations use this to signal that the peer indicated a protocol
254 * version downgrade. After calling `request_downgrade()` no further
255 * state changes must be perfomed by the implementation. Particularly, no
256 * further handshake messages must be emitted. Instead, they must yield
257 * control flow back to the underlying Channel implementation to perform
258 * the protocol version downgrade.
259 */
262 m_downgrade_info->will_downgrade = true;
263 }
264
266 BOTAN_STATE_CHECK(m_downgrade_info && m_downgrade_info->client_hello_message.empty() &&
267 m_downgrade_info->peer_transcript.empty() && !m_downgrade_info->tls12_session.has_value());
269 m_downgrade_info->tls12_session = std::move(session);
271 }
272
273 public:
274 /**
275 * Indicates whether a downgrade to TLS 1.2 or lower is in progress
276 *
277 * @sa Downgrade_Information
278 */
279 bool is_downgrading() const { return m_downgrade_info && m_downgrade_info->will_downgrade; }
280
281 /**
282 * @sa Downgrade_Information
283 */
284 std::unique_ptr<Downgrade_Information> extract_downgrade_info() { return std::exchange(m_downgrade_info, {}); }
285
286 bool expects_downgrade() const { return m_downgrade_info != nullptr; }
287};
288
289} // namespace TLS
290
291} // namespace Botan
292
293#endif
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
AlertType Type
Definition tls_alert.h:71
virtual std::optional< std::string > external_psk_identity() const =0
virtual SymmetricKey key_material_export(std::string_view label, std::string_view context, size_t length) const =0
virtual bool is_active() const =0
void preserve_peer_transcript(std::span< const uint8_t > input)
virtual std::string application_protocol() const =0
Channel_Impl(Channel_Impl &&other)=default
virtual bool new_session_ticket_supported() const
virtual ~Channel_Impl()=default
void request_downgrade_for_resumption(Session_with_Handle session)
void preserve_client_hello(std::span< const uint8_t > msg)
virtual size_t from_peer(std::span< const uint8_t > data)=0
Channel_Impl & operator=(Channel_Impl &&other)=delete
virtual bool timeout_check()=0
virtual bool is_closed_for_reading() const =0
virtual void update_traffic_keys(bool request_peer_update=false)=0
virtual void send_alert(const Alert &alert)=0
virtual void to_peer(std::span< const uint8_t > data)=0
virtual bool is_closed() const =0
void send_warning_alert(Alert::Type type)
virtual bool secure_renegotiation_supported() const =0
std::unique_ptr< Downgrade_Information > extract_downgrade_info()
virtual bool is_closed_for_writing() const =0
virtual std::shared_ptr< const Public_Key > peer_raw_public_key() const =0
void send_fatal_alert(Alert::Type type)
void set_io_buffer_size(size_t io_buf_sz)
virtual void renegotiate(bool force_full_renegotiation=false)=0
std::unique_ptr< Downgrade_Information > m_downgrade_info
virtual std::vector< X509_Certificate > peer_cert_chain() const =0
Channel_Impl(const Channel_Impl &other)=delete
virtual bool is_handshake_complete() const =0
virtual size_t send_new_session_tickets(const size_t)
Channel_Impl & operator=(const Channel_Impl &other)=delete
Protocol_Version version() const
OctetString SymmetricKey
Definition symkey.h:140
std::vector< uint8_t > peer_transcript
The full data transcript received from the peer. This will contain the server hello message that forc...
std::vector< uint8_t > client_hello_message
The client hello message including the handshake header bytes as transferred to the peer.
std::shared_ptr< Session_Manager > session_manager
std::shared_ptr< Credentials_Manager > creds
std::optional< Session_with_Handle > tls12_session
std::shared_ptr< RandomNumberGenerator > rng