/src/boringssl/ssl/s3_pkt.cc
Line | Count | Source |
1 | | // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <openssl/ssl.h> |
16 | | |
17 | | #include <assert.h> |
18 | | #include <limits.h> |
19 | | #include <string.h> |
20 | | |
21 | | #include <algorithm> |
22 | | |
23 | | #include <openssl/err.h> |
24 | | #include <openssl/evp.h> |
25 | | #include <openssl/mem.h> |
26 | | #include <openssl/rand.h> |
27 | | |
28 | | #include "../crypto/err/internal.h" |
29 | | #include "../crypto/internal.h" |
30 | | #include "internal.h" |
31 | | |
32 | | |
33 | | BSSL_NAMESPACE_BEGIN |
34 | | |
35 | | static int do_tls_write(SSLImpl *ssl, size_t *out_bytes_written, uint8_t type, |
36 | | Span<const uint8_t> in); |
37 | | |
38 | | int tls_write_app_data(SSLImpl *ssl, bool *out_needs_handshake, |
39 | 0 | size_t *out_bytes_written, Span<const uint8_t> in) { |
40 | 0 | assert(ssl_can_write(ssl)); |
41 | 0 | assert(!ssl->s3->aead_write_ctx->is_null_cipher()); |
42 | | |
43 | 0 | *out_needs_handshake = false; |
44 | |
|
45 | 0 | if (ssl->s3->write_shutdown != ssl_shutdown_none) { |
46 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); |
47 | 0 | return -1; |
48 | 0 | } |
49 | | |
50 | 0 | size_t total_bytes_written = ssl->s3->unreported_bytes_written; |
51 | 0 | if (in.size() < total_bytes_written) { |
52 | | // This can happen if the caller disables `SSL_MODE_ENABLE_PARTIAL_WRITE`, |
53 | | // asks us to write some input of length N, we successfully encrypt M bytes |
54 | | // and write it, but fail to write the rest. We will report |
55 | | // `SSL_ERROR_WANT_WRITE`. If the caller then retries with fewer than M |
56 | | // bytes, we cannot satisfy that request. The caller is required to always |
57 | | // retry with at least as many bytes as the previous attempt. |
58 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); |
59 | 0 | return -1; |
60 | 0 | } |
61 | | |
62 | 0 | in = in.subspan(total_bytes_written); |
63 | |
|
64 | 0 | const bool is_early_data_write = |
65 | 0 | !ssl->server && SSL_in_early_data(ssl) && ssl->s3->hs->can_early_write; |
66 | 0 | for (;;) { |
67 | 0 | size_t max_send_fragment = ssl->max_send_fragment; |
68 | 0 | if (is_early_data_write) { |
69 | 0 | SSL_HANDSHAKE *hs = ssl->s3->hs.get(); |
70 | 0 | if (hs->early_data_written >= hs->early_session->ticket_max_early_data) { |
71 | 0 | ssl->s3->unreported_bytes_written = total_bytes_written; |
72 | 0 | hs->can_early_write = false; |
73 | 0 | *out_needs_handshake = true; |
74 | 0 | return -1; |
75 | 0 | } |
76 | 0 | max_send_fragment = std::min( |
77 | 0 | max_send_fragment, size_t{hs->early_session->ticket_max_early_data - |
78 | 0 | hs->early_data_written}); |
79 | 0 | } |
80 | | |
81 | 0 | const size_t to_write = std::min(max_send_fragment, in.size()); |
82 | 0 | size_t bytes_written; |
83 | 0 | int ret = do_tls_write(ssl, &bytes_written, SSL3_RT_APPLICATION_DATA, |
84 | 0 | in.subspan(0, to_write)); |
85 | 0 | if (ret <= 0) { |
86 | 0 | ssl->s3->unreported_bytes_written = total_bytes_written; |
87 | 0 | return ret; |
88 | 0 | } |
89 | | |
90 | | // Note `bytes_written` may be less than `to_write` if there was a pending |
91 | | // record from a smaller write attempt. |
92 | 0 | assert(bytes_written <= to_write); |
93 | 0 | total_bytes_written += bytes_written; |
94 | 0 | in = in.subspan(bytes_written); |
95 | 0 | if (is_early_data_write) { |
96 | 0 | ssl->s3->hs->early_data_written += bytes_written; |
97 | 0 | } |
98 | |
|
99 | 0 | if (in.empty() || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { |
100 | 0 | ssl->s3->unreported_bytes_written = 0; |
101 | 0 | *out_bytes_written = total_bytes_written; |
102 | 0 | return 1; |
103 | 0 | } |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | | // tls_seal_align_prefix_len returns the length of the prefix before the start |
108 | | // of the bulk of the ciphertext when sealing a record with `ssl`. Callers may |
109 | | // use this to align buffers. |
110 | | // |
111 | | // Note when TLS 1.0 CBC record-splitting is enabled, this includes the one byte |
112 | | // record and is the offset into second record's ciphertext. Thus sealing a |
113 | | // small record may result in a smaller output than this value. |
114 | | // |
115 | | // TODO(davidben): Is this alignment valuable? Record-splitting makes this a |
116 | | // mess. |
117 | 11.3k | static size_t tls_seal_align_prefix_len(const SSLImpl *ssl) { |
118 | 11.3k | size_t ret = |
119 | 11.3k | SSL3_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen(); |
120 | 11.3k | if (ssl_needs_record_splitting(ssl)) { |
121 | 0 | ret += SSL3_RT_HEADER_LENGTH; |
122 | 0 | ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher()); |
123 | 0 | } |
124 | 11.3k | return ret; |
125 | 11.3k | } |
126 | | |
127 | | // do_tls_write writes an SSL record of the given type. On success, it sets |
128 | | // `*out_bytes_written` to number of bytes successfully written and returns one. |
129 | | // On error, it returns a value <= 0 from the underlying `BIO`. |
130 | | static int do_tls_write(SSLImpl *ssl, size_t *out_bytes_written, uint8_t type, |
131 | 11.3k | Span<const uint8_t> in) { |
132 | | // If there is a pending write, the retry must be consistent. |
133 | 11.3k | if (!ssl->s3->pending_write.empty() && |
134 | 0 | (ssl->s3->pending_write.size() > in.size() || |
135 | 0 | (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && |
136 | 0 | ssl->s3->pending_write.data() != in.data()) || |
137 | 0 | ssl->s3->pending_write_type != type)) { |
138 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY); |
139 | 0 | return -1; |
140 | 0 | } |
141 | | |
142 | | // Flush any unwritten data to the transport. There may be data to flush even |
143 | | // if `wpend_tot` is zero. |
144 | 11.3k | int ret = ssl_write_buffer_flush(ssl); |
145 | 11.3k | if (ret <= 0) { |
146 | 0 | return ret; |
147 | 0 | } |
148 | | |
149 | | // If there is a pending write, we just completed it. Report it to the caller. |
150 | 11.3k | if (!ssl->s3->pending_write.empty()) { |
151 | 0 | *out_bytes_written = ssl->s3->pending_write.size(); |
152 | 0 | ssl->s3->pending_write = {}; |
153 | 0 | return 1; |
154 | 0 | } |
155 | | |
156 | 11.3k | SSLBuffer *buf = &ssl->s3->write_buffer; |
157 | 11.3k | if (in.size() > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) { |
158 | 0 | OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); |
159 | 0 | return -1; |
160 | 0 | } |
161 | | |
162 | 11.3k | if (!tls_flush_pending_hs_data(ssl)) { |
163 | 0 | return -1; |
164 | 0 | } |
165 | | |
166 | | // We may have unflushed handshake data that must be written before `in`. This |
167 | | // may be a KeyUpdate acknowledgment, 0-RTT key change messages, or a |
168 | | // NewSessionTicket. |
169 | 11.3k | Span<const uint8_t> pending_flight; |
170 | 11.3k | if (ssl->s3->pending_flight != nullptr) { |
171 | 458 | pending_flight = |
172 | 458 | Span(reinterpret_cast<const uint8_t *>(ssl->s3->pending_flight->data), |
173 | 458 | ssl->s3->pending_flight->length); |
174 | 458 | pending_flight = pending_flight.subspan(ssl->s3->pending_flight_offset); |
175 | 458 | } |
176 | | |
177 | 11.3k | size_t max_out = pending_flight.size(); |
178 | 11.3k | if (!in.empty()) { |
179 | 11.3k | const size_t max_ciphertext_len = in.size() + SSL_max_seal_overhead(ssl); |
180 | 11.3k | if (max_ciphertext_len < in.size() || |
181 | 11.3k | max_out + max_ciphertext_len < max_out) { |
182 | 0 | OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); |
183 | 0 | return -1; |
184 | 0 | } |
185 | 11.3k | max_out += max_ciphertext_len; |
186 | 11.3k | } |
187 | | |
188 | 11.3k | if (max_out == 0) { |
189 | | // Nothing to write. |
190 | 0 | *out_bytes_written = 0; |
191 | 0 | return 1; |
192 | 0 | } |
193 | | |
194 | 11.3k | if (!buf->EnsureCap(pending_flight.size() + tls_seal_align_prefix_len(ssl), |
195 | 11.3k | max_out)) { |
196 | 0 | return -1; |
197 | 0 | } |
198 | | |
199 | | // Copy `pending_flight` to the output. |
200 | 11.3k | if (!pending_flight.empty()) { |
201 | 458 | OPENSSL_memcpy(buf->remaining().data(), pending_flight.data(), |
202 | 458 | pending_flight.size()); |
203 | 458 | ssl->s3->pending_flight.reset(); |
204 | 458 | ssl->s3->pending_flight_offset = 0; |
205 | 458 | buf->DidWrite(pending_flight.size()); |
206 | 458 | } |
207 | | |
208 | 11.3k | if (!in.empty()) { |
209 | 11.3k | size_t ciphertext_len; |
210 | 11.3k | if (!tls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, |
211 | 11.3k | buf->remaining().size(), type, in.data(), in.size())) { |
212 | 0 | return -1; |
213 | 0 | } |
214 | 11.3k | buf->DidWrite(ciphertext_len); |
215 | 11.3k | } |
216 | | |
217 | | // Now that we've made progress on the connection, uncork KeyUpdate |
218 | | // acknowledgments. |
219 | 11.3k | ssl->s3->key_update_pending = false; |
220 | | |
221 | | // Flush the write buffer. |
222 | 11.3k | ret = ssl_write_buffer_flush(ssl); |
223 | 11.3k | if (ret <= 0) { |
224 | | // Track the unfinished write. |
225 | 0 | if (!in.empty()) { |
226 | 0 | ssl->s3->pending_write = in; |
227 | 0 | ssl->s3->pending_write_type = type; |
228 | 0 | } |
229 | 0 | return ret; |
230 | 0 | } |
231 | | |
232 | 11.3k | *out_bytes_written = in.size(); |
233 | 11.3k | return 1; |
234 | 11.3k | } |
235 | | |
236 | | ssl_open_record_t tls_open_app_data(SSLImpl *ssl, Span<uint8_t> *out, |
237 | | size_t *out_consumed, uint8_t *out_alert, |
238 | 336k | Span<uint8_t> in) { |
239 | 336k | assert(ssl_can_read(ssl)); |
240 | 336k | assert(!ssl->s3->aead_read_ctx->is_null_cipher()); |
241 | | |
242 | 336k | uint8_t type; |
243 | 336k | Span<uint8_t> body; |
244 | 336k | auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); |
245 | 336k | if (ret != ssl_open_record_success) { |
246 | 208k | return ret; |
247 | 208k | } |
248 | | |
249 | 127k | const bool is_early_data_read = ssl->server && SSL_in_early_data(ssl); |
250 | | |
251 | 127k | if (type == SSL3_RT_HANDSHAKE) { |
252 | | // Post-handshake data prior to TLS 1.3 is always renegotiation, which we |
253 | | // never accept as a server. Otherwise `tls_get_message` will send |
254 | | // `SSL_R_EXCESSIVE_MESSAGE_SIZE`. |
255 | 54.7k | if (ssl->server && ssl_protocol_version(ssl) < TLS1_3_VERSION) { |
256 | 1 | OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); |
257 | 1 | *out_alert = SSL_AD_NO_RENEGOTIATION; |
258 | 1 | return ssl_open_record_error; |
259 | 1 | } |
260 | | |
261 | 54.7k | if (!tls_append_handshake_data(ssl, body)) { |
262 | 0 | *out_alert = SSL_AD_INTERNAL_ERROR; |
263 | 0 | return ssl_open_record_error; |
264 | 0 | } |
265 | 54.7k | return ssl_open_record_discard; |
266 | 54.7k | } |
267 | | |
268 | 72.8k | if (type != SSL3_RT_APPLICATION_DATA) { |
269 | 73 | OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); |
270 | 73 | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; |
271 | 73 | return ssl_open_record_error; |
272 | 73 | } |
273 | | |
274 | 72.7k | if (is_early_data_read) { |
275 | 336 | if (body.size() > kMaxEarlyDataAccepted - ssl->s3->hs->early_data_read) { |
276 | 5 | OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_READ_EARLY_DATA); |
277 | 5 | *out_alert = SSL3_AD_UNEXPECTED_MESSAGE; |
278 | 5 | return ssl_open_record_error; |
279 | 5 | } |
280 | | |
281 | 331 | ssl->s3->hs->early_data_read += body.size(); |
282 | 331 | } |
283 | | |
284 | 72.7k | if (body.empty()) { |
285 | 47.9k | return ssl_open_record_discard; |
286 | 47.9k | } |
287 | | |
288 | 24.7k | *out = body; |
289 | 24.7k | return ssl_open_record_success; |
290 | 72.7k | } |
291 | | |
292 | | ssl_open_record_t tls_open_change_cipher_spec(SSLImpl *ssl, |
293 | | size_t *out_consumed, |
294 | | uint8_t *out_alert, |
295 | 119k | Span<uint8_t> in) { |
296 | 119k | uint8_t type; |
297 | 119k | Span<uint8_t> body; |
298 | 119k | auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); |
299 | 119k | if (ret != ssl_open_record_success) { |
300 | 80.7k | return ret; |
301 | 80.7k | } |
302 | | |
303 | 39.1k | if (type != SSL3_RT_CHANGE_CIPHER_SPEC) { |
304 | 32 | OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); |
305 | 32 | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; |
306 | 32 | return ssl_open_record_error; |
307 | 32 | } |
308 | | |
309 | 39.0k | if (body.size() != 1 || body[0] != SSL3_MT_CCS) { |
310 | 35 | OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); |
311 | 35 | *out_alert = SSL_AD_ILLEGAL_PARAMETER; |
312 | 35 | return ssl_open_record_error; |
313 | 35 | } |
314 | | |
315 | 39.0k | ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, body); |
316 | 39.0k | return ssl_open_record_success; |
317 | 39.0k | } |
318 | | |
319 | 15.7k | void ssl_send_alert(SSLImpl *ssl, int level, int desc) { |
320 | | // This function is called in response to a fatal error from the peer. Ignore |
321 | | // any failures writing the alert and report only the original error. In |
322 | | // particular, if the transport uses `SSL_write`, our existing error will be |
323 | | // clobbered so we must save and restore the error queue. See |
324 | | // https://crbug.com/959305. |
325 | | // |
326 | | // TODO(davidben): Return the alert out of the handshake, rather than calling |
327 | | // this function internally everywhere. |
328 | | // |
329 | | // TODO(davidben): This does not allow retrying if the alert hit EAGAIN. See |
330 | | // https://crbug.com/boringssl/130. |
331 | 15.7k | UniquePtr<ERR_SAVE_STATE> err_state(ERR_save_state()); |
332 | 15.7k | ssl_send_alert_impl(ssl, level, desc); |
333 | 15.7k | ERR_restore_state(err_state.get()); |
334 | 15.7k | } |
335 | | |
336 | 15.7k | int ssl_send_alert_impl(SSLImpl *ssl, int level, int desc) { |
337 | | // It is illegal to send an alert when we've already sent a closing one. |
338 | 15.7k | if (ssl->s3->write_shutdown != ssl_shutdown_none) { |
339 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); |
340 | 0 | return -1; |
341 | 0 | } |
342 | | |
343 | 15.7k | if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) { |
344 | 0 | ssl->s3->write_shutdown = ssl_shutdown_close_notify; |
345 | 15.7k | } else { |
346 | 15.7k | assert(level == SSL3_AL_FATAL); |
347 | 15.7k | assert(desc != SSL_AD_CLOSE_NOTIFY); |
348 | 15.7k | ssl->s3->write_shutdown = ssl_shutdown_error; |
349 | 15.7k | } |
350 | | |
351 | 15.7k | ssl->s3->alert_dispatch = true; |
352 | 15.7k | ssl->s3->send_alert[0] = level; |
353 | 15.7k | ssl->s3->send_alert[1] = desc; |
354 | 15.7k | if (ssl->s3->write_buffer.empty()) { |
355 | | // Nothing is being written out, so the alert may be dispatched |
356 | | // immediately. |
357 | 15.7k | return ssl->method->dispatch_alert(ssl); |
358 | 15.7k | } |
359 | | |
360 | | // The alert will be dispatched later. |
361 | 0 | return -1; |
362 | 15.7k | } |
363 | | |
364 | 11.3k | int tls_dispatch_alert(SSLImpl *ssl) { |
365 | 11.3k | if (SSL_is_quic(ssl)) { |
366 | 0 | if (!ssl->quic_method->send_alert(ssl, ssl->s3->quic_write_level, |
367 | 0 | ssl->s3->send_alert[1])) { |
368 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR); |
369 | 0 | return 0; |
370 | 0 | } |
371 | 11.3k | } else { |
372 | 11.3k | size_t bytes_written; |
373 | 11.3k | int ret = |
374 | 11.3k | do_tls_write(ssl, &bytes_written, SSL3_RT_ALERT, ssl->s3->send_alert); |
375 | 11.3k | if (ret <= 0) { |
376 | 0 | return ret; |
377 | 0 | } |
378 | 11.3k | assert(bytes_written == 2); |
379 | 11.3k | } |
380 | | |
381 | 11.3k | ssl->s3->alert_dispatch = false; |
382 | | |
383 | | // If the alert is fatal, flush the BIO now. |
384 | 11.3k | if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { |
385 | 11.3k | BIO_flush(ssl->wbio.get()); |
386 | 11.3k | } |
387 | | |
388 | 11.3k | ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); |
389 | | |
390 | 11.3k | int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; |
391 | 11.3k | ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); |
392 | | |
393 | 11.3k | return 1; |
394 | 11.3k | } |
395 | | |
396 | | BSSL_NAMESPACE_END |