/src/botan/build/include/botan/internal/tls_channel_impl.h
Line | Count | Source (jump to first uncovered line) |
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/tls_channel.h> |
15 | | #include <botan/tls_version.h> |
16 | | #include <botan/tls_magic.h> |
17 | | |
18 | | #include <vector> |
19 | | #include <memory> |
20 | | #include <utility> |
21 | | |
22 | | namespace Botan { |
23 | | |
24 | | class Credentials_Manager; |
25 | | class X509_Certificate; |
26 | | |
27 | | namespace TLS { |
28 | | |
29 | | class Client; |
30 | | class Server; |
31 | | |
32 | | class Channel_Impl |
33 | | { |
34 | | public: |
35 | 8.33k | virtual ~Channel_Impl() = default; |
36 | | |
37 | | /** |
38 | | * Inject TLS traffic received from counterparty |
39 | | * @return a hint as the how many more bytes we need to q the |
40 | | * current record (this may be 0 if on a record boundary) |
41 | | */ |
42 | | virtual size_t received_data(const uint8_t buf[], size_t buf_size) = 0; |
43 | | |
44 | | /** |
45 | | * Inject plaintext intended for counterparty |
46 | | * Throws an exception if is_active() is false |
47 | | */ |
48 | | virtual void send(const uint8_t buf[], size_t buf_size) = 0; |
49 | | |
50 | | /** |
51 | | * Send a TLS alert message. If the alert is fatal, the internal |
52 | | * state (keys, etc) will be reset. |
53 | | * @param alert the Alert to send |
54 | | */ |
55 | | virtual void send_alert(const Alert& alert) = 0; |
56 | | |
57 | | /** |
58 | | * Send a warning alert |
59 | | */ |
60 | 938 | void send_warning_alert(Alert::Type type) { send_alert(Alert(type, false)); } |
61 | | |
62 | | /** |
63 | | * Send a fatal alert |
64 | | */ |
65 | 5.52k | void send_fatal_alert(Alert::Type type) { send_alert(Alert(type, true)); } |
66 | | |
67 | | /** |
68 | | * Send a close notification alert |
69 | | */ |
70 | 0 | void close() { send_warning_alert(Alert::CLOSE_NOTIFY); } |
71 | | |
72 | | /** |
73 | | * @return true iff the connection is active for sending application data |
74 | | */ |
75 | | virtual bool is_active() const = 0; |
76 | | |
77 | | /** |
78 | | * @return true iff the connection has been definitely closed |
79 | | */ |
80 | | virtual bool is_closed() const = 0; |
81 | | |
82 | | /** |
83 | | * @return true iff the connection is active for sending application data |
84 | | */ |
85 | | virtual bool is_closed_for_reading() const = 0; |
86 | | |
87 | | /** |
88 | | * @return true iff the connection has been definitely closed |
89 | | */ |
90 | | virtual bool is_closed_for_writing() const = 0; |
91 | | |
92 | | /** |
93 | | * @return certificate chain of the peer (may be empty) |
94 | | */ |
95 | | virtual std::vector<X509_Certificate> peer_cert_chain() const = 0; |
96 | | |
97 | | /** |
98 | | * Key material export (RFC 5705) |
99 | | * @param label a disambiguating label string |
100 | | * @param context a per-association context value |
101 | | * @param length the length of the desired key in bytes |
102 | | * @return key of length bytes |
103 | | */ |
104 | | virtual SymmetricKey key_material_export(const std::string& label, |
105 | | const std::string& context, |
106 | | size_t length) const = 0; |
107 | | |
108 | | /** |
109 | | * Attempt to renegotiate the session |
110 | | * @param force_full_renegotiation if true, require a full renegotiation, |
111 | | * otherwise allow session resumption |
112 | | */ |
113 | | virtual void renegotiate(bool force_full_renegotiation = false) = 0; |
114 | | |
115 | | /** |
116 | | * Attempt to update the session's traffic key material |
117 | | * Note that this is possible with a TLS 1.3 channel, only. |
118 | | * |
119 | | * @param request_peer_update if true, require a reciprocal key update |
120 | | */ |
121 | | virtual void update_traffic_keys(bool request_peer_update = false) = 0; |
122 | | |
123 | | /** |
124 | | * @return true iff the counterparty supports the secure |
125 | | * renegotiation extensions. |
126 | | */ |
127 | | virtual bool secure_renegotiation_supported() const = 0; |
128 | | |
129 | | /** |
130 | | * Perform a handshake timeout check. This does nothing unless |
131 | | * this is a DTLS channel with a pending handshake state, in |
132 | | * which case we check for timeout and potentially retransmit |
133 | | * handshake packets. |
134 | | */ |
135 | | virtual bool timeout_check() = 0; |
136 | | |
137 | | /** |
138 | | * Return the protocol notification set for this connection, if any (ALPN). |
139 | | * This value is not tied to the session and a later renegotiation of the |
140 | | * same session can choose a new protocol. |
141 | | */ |
142 | | virtual std::string application_protocol() const = 0; |
143 | | |
144 | | protected: |
145 | | /** |
146 | | * This struct collect all information required to perform a downgrade from TLS 1.3 to TLS 1.2. |
147 | | * |
148 | | * The downgrade process is (currently) triggered when a TLS 1.3 client receives a downgrade request |
149 | | * in the server hello message (@sa `Client_Impl_13::handle(Server_Hello_12)`). As a result, |
150 | | * `Client::received_data` should detect this condition and replace its `Channel_Impl_13` member by a |
151 | | * `Channel_Impl_12`. |
152 | | * |
153 | | * Note that the downgrade process for the server implementation will likely differ. |
154 | | */ |
155 | | struct Downgrade_Information |
156 | | { |
157 | | /// The client hello message including the handshake header bytes as transferred to the peer. |
158 | | std::vector<uint8_t> client_hello_message; |
159 | | |
160 | | /// The full data transcript received from the peer. This will contain the server hello message that forced us to downgrade. |
161 | | std::vector<uint8_t> peer_transcript; |
162 | | |
163 | | Server_Information server_info; |
164 | | size_t io_buffer_size; |
165 | | |
166 | | Callbacks& callbacks; |
167 | | Session_Manager& session_manager; |
168 | | Credentials_Manager& creds; |
169 | | RandomNumberGenerator& rng; |
170 | | const Policy& policy; |
171 | | |
172 | | bool received_tls_13_error_alert; |
173 | | bool will_downgrade; |
174 | | }; |
175 | | |
176 | | std::unique_ptr<Downgrade_Information> m_downgrade_info; |
177 | | |
178 | | void preserve_peer_transcript(const uint8_t input[], size_t input_size) |
179 | 0 | { |
180 | 0 | BOTAN_STATE_CHECK(m_downgrade_info); |
181 | 0 | m_downgrade_info->peer_transcript.insert(m_downgrade_info->peer_transcript.end(), |
182 | 0 | input, input+input_size); |
183 | 0 | } |
184 | | |
185 | | void preserve_client_hello(const std::vector<uint8_t>& msg) |
186 | 0 | { |
187 | 0 | BOTAN_STATE_CHECK(m_downgrade_info); |
188 | 0 | m_downgrade_info->client_hello_message = msg; |
189 | 0 | } Unexecuted instantiation: Botan::TLS::Channel_Impl::preserve_client_hello(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&) Unexecuted instantiation: Botan::TLS::Channel_Impl::preserve_client_hello(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&) |
190 | | |
191 | | friend class Client; |
192 | | friend class Server; |
193 | | void set_io_buffer_size(size_t io_buf_sz) |
194 | 0 | { |
195 | 0 | BOTAN_STATE_CHECK(m_downgrade_info); |
196 | 0 | m_downgrade_info->io_buffer_size = io_buf_sz; |
197 | 0 | } |
198 | | |
199 | | /** |
200 | | * Implementations use this to signal that the peer indicated a protocol |
201 | | * version downgrade. After calling `request_downgrade()` no further |
202 | | * state changes must be perfomed by the implementation. Particularly, no |
203 | | * further handshake messages must be emitted. Instead, they must yield |
204 | | * control flow back to the underlying Channel implementation to perform |
205 | | * the protocol version downgrade. |
206 | | */ |
207 | | void request_downgrade() |
208 | 0 | { |
209 | 0 | BOTAN_STATE_CHECK(m_downgrade_info && !m_downgrade_info->will_downgrade); |
210 | 0 | m_downgrade_info->will_downgrade = true; |
211 | 0 | } |
212 | | |
213 | | public: |
214 | | /** |
215 | | * Indicates whether a downgrade to TLS 1.2 or lower is in progress |
216 | | * |
217 | | * @sa Downgrade_Information |
218 | | */ |
219 | 2.80k | bool is_downgrading() const { return m_downgrade_info && m_downgrade_info->will_downgrade; } |
220 | | |
221 | | /** |
222 | | * @sa Downgrade_Information |
223 | | */ |
224 | 0 | std::unique_ptr<Downgrade_Information> extract_downgrade_info() { return std::exchange(m_downgrade_info, {}); } |
225 | | |
226 | 0 | bool expects_downgrade() const { return m_downgrade_info != nullptr; } |
227 | | }; |
228 | | |
229 | | } |
230 | | |
231 | | } |
232 | | |
233 | | #endif |