1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57 /* ====================================================================
58 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com). */
108
109 #include <openssl/ssl.h>
110
111 #include <assert.h>
112 #include <limits.h>
113 #include <string.h>
114
115 #include <openssl/err.h>
116 #include <openssl/evp.h>
117 #include <openssl/mem.h>
118 #include <openssl/rand.h>
119
120 #include "../crypto/err/internal.h"
121 #include "../crypto/internal.h"
122 #include "internal.h"
123
124
125 BSSL_NAMESPACE_BEGIN
126
127 static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len);
128
tls_write_app_data(SSL * ssl,bool * out_needs_handshake,const uint8_t * in,int len)129 int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in,
130 int len) {
131 assert(ssl_can_write(ssl));
132 assert(!ssl->s3->aead_write_ctx->is_null_cipher());
133
134 *out_needs_handshake = false;
135
136 if (ssl->s3->write_shutdown != ssl_shutdown_none) {
137 OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
138 return -1;
139 }
140
141 unsigned tot, n, nw;
142
143 assert(ssl->s3->wnum <= INT_MAX);
144 tot = ssl->s3->wnum;
145 ssl->s3->wnum = 0;
146
147 // Ensure that if we end up with a smaller value of data to write out than
148 // the the original len from a write which didn't complete for non-blocking
149 // I/O and also somehow ended up avoiding the check for this in
150 // tls_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be possible to
151 // end up with (len-tot) as a large number that will then promptly send
152 // beyond the end of the users buffer ... so we trap and report the error in
153 // a way the user will notice.
154 if (len < 0 || (size_t)len < tot) {
155 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
156 return -1;
157 }
158
159 const int is_early_data_write =
160 !ssl->server && SSL_in_early_data(ssl) && ssl->s3->hs->can_early_write;
161
162 n = len - tot;
163 for (;;) {
164 // max contains the maximum number of bytes that we can put into a record.
165 unsigned max = ssl->max_send_fragment;
166 if (is_early_data_write &&
167 max > ssl->session->ticket_max_early_data -
168 ssl->s3->hs->early_data_written) {
169 max =
170 ssl->session->ticket_max_early_data - ssl->s3->hs->early_data_written;
171 if (max == 0) {
172 ssl->s3->wnum = tot;
173 ssl->s3->hs->can_early_write = false;
174 *out_needs_handshake = true;
175 return -1;
176 }
177 }
178
179 if (n > max) {
180 nw = max;
181 } else {
182 nw = n;
183 }
184
185 int ret = do_tls_write(ssl, SSL3_RT_APPLICATION_DATA, &in[tot], nw);
186 if (ret <= 0) {
187 ssl->s3->wnum = tot;
188 return ret;
189 }
190
191 if (is_early_data_write) {
192 ssl->s3->hs->early_data_written += ret;
193 }
194
195 if (ret == (int)n || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) {
196 return tot + ret;
197 }
198
199 n -= ret;
200 tot += ret;
201 }
202 }
203
tls_write_pending(SSL * ssl,int type,const uint8_t * in,unsigned int len)204 static int tls_write_pending(SSL *ssl, int type, const uint8_t *in,
205 unsigned int len) {
206 if (ssl->s3->wpend_tot > (int)len ||
207 (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) &&
208 ssl->s3->wpend_buf != in) ||
209 ssl->s3->wpend_type != type) {
210 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY);
211 return -1;
212 }
213
214 int ret = ssl_write_buffer_flush(ssl);
215 if (ret <= 0) {
216 return ret;
217 }
218 ssl->s3->wpend_pending = false;
219 return ssl->s3->wpend_ret;
220 }
221
222 // do_tls_write writes an SSL record of the given type.
do_tls_write(SSL * ssl,int type,const uint8_t * in,unsigned len)223 static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len) {
224 // If there is still data from the previous record, flush it.
225 if (ssl->s3->wpend_pending) {
226 return tls_write_pending(ssl, type, in, len);
227 }
228
229 SSLBuffer *buf = &ssl->s3->write_buffer;
230 if (len > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) {
231 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
232 return -1;
233 }
234
235 if (!tls_flush_pending_hs_data(ssl)) {
236 return -1;
237 }
238
239 size_t flight_len = 0;
240 if (ssl->s3->pending_flight != nullptr) {
241 flight_len =
242 ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset;
243 }
244
245 size_t max_out = flight_len;
246 if (len > 0) {
247 const size_t max_ciphertext_len = len + SSL_max_seal_overhead(ssl);
248 if (max_ciphertext_len < len || max_out + max_ciphertext_len < max_out) {
249 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
250 return -1;
251 }
252 max_out += max_ciphertext_len;
253 }
254
255 if (max_out == 0) {
256 return 0;
257 }
258
259 if (!buf->EnsureCap(flight_len + ssl_seal_align_prefix_len(ssl), max_out)) {
260 return -1;
261 }
262
263 // Add any unflushed handshake data as a prefix. This may be a KeyUpdate
264 // acknowledgment or 0-RTT key change messages. |pending_flight| must be clear
265 // when data is added to |write_buffer| or it will be written in the wrong
266 // order.
267 if (ssl->s3->pending_flight != nullptr) {
268 OPENSSL_memcpy(
269 buf->remaining().data(),
270 ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset,
271 flight_len);
272 ssl->s3->pending_flight.reset();
273 ssl->s3->pending_flight_offset = 0;
274 buf->DidWrite(flight_len);
275 }
276
277 if (len > 0) {
278 size_t ciphertext_len;
279 if (!tls_seal_record(ssl, buf->remaining().data(), &ciphertext_len,
280 buf->remaining().size(), type, in, len)) {
281 return -1;
282 }
283 buf->DidWrite(ciphertext_len);
284 }
285
286 // Now that we've made progress on the connection, uncork KeyUpdate
287 // acknowledgments.
288 ssl->s3->key_update_pending = false;
289
290 // Memorize arguments so that tls_write_pending can detect bad write retries
291 // later.
292 ssl->s3->wpend_tot = len;
293 ssl->s3->wpend_buf = in;
294 ssl->s3->wpend_type = type;
295 ssl->s3->wpend_ret = len;
296 ssl->s3->wpend_pending = true;
297
298 // We now just need to write the buffer.
299 return tls_write_pending(ssl, type, in, len);
300 }
301
tls_open_app_data(SSL * ssl,Span<uint8_t> * out,size_t * out_consumed,uint8_t * out_alert,Span<uint8_t> in)302 ssl_open_record_t tls_open_app_data(SSL *ssl, Span<uint8_t> *out,
303 size_t *out_consumed, uint8_t *out_alert,
304 Span<uint8_t> in) {
305 assert(ssl_can_read(ssl));
306 assert(!ssl->s3->aead_read_ctx->is_null_cipher());
307
308 uint8_t type;
309 Span<uint8_t> body;
310 auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in);
311 if (ret != ssl_open_record_success) {
312 return ret;
313 }
314
315 const bool is_early_data_read = ssl->server && SSL_in_early_data(ssl);
316
317 if (type == SSL3_RT_HANDSHAKE) {
318 // Post-handshake data prior to TLS 1.3 is always renegotiation, which we
319 // never accept as a server. Otherwise |tls_get_message| will send
320 // |SSL_R_EXCESSIVE_MESSAGE_SIZE|.
321 if (ssl->server && ssl_protocol_version(ssl) < TLS1_3_VERSION) {
322 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
323 *out_alert = SSL_AD_NO_RENEGOTIATION;
324 return ssl_open_record_error;
325 }
326
327 if (!tls_append_handshake_data(ssl, body)) {
328 *out_alert = SSL_AD_INTERNAL_ERROR;
329 return ssl_open_record_error;
330 }
331 return ssl_open_record_discard;
332 }
333
334 if (type != SSL3_RT_APPLICATION_DATA) {
335 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
336 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
337 return ssl_open_record_error;
338 }
339
340 if (is_early_data_read) {
341 if (body.size() > kMaxEarlyDataAccepted - ssl->s3->hs->early_data_read) {
342 OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_READ_EARLY_DATA);
343 *out_alert = SSL3_AD_UNEXPECTED_MESSAGE;
344 return ssl_open_record_error;
345 }
346
347 ssl->s3->hs->early_data_read += body.size();
348 }
349
350 if (body.empty()) {
351 return ssl_open_record_discard;
352 }
353
354 *out = body;
355 return ssl_open_record_success;
356 }
357
tls_open_change_cipher_spec(SSL * ssl,size_t * out_consumed,uint8_t * out_alert,Span<uint8_t> in)358 ssl_open_record_t tls_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
359 uint8_t *out_alert,
360 Span<uint8_t> in) {
361 uint8_t type;
362 Span<uint8_t> body;
363 auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in);
364 if (ret != ssl_open_record_success) {
365 return ret;
366 }
367
368 if (type != SSL3_RT_CHANGE_CIPHER_SPEC) {
369 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
370 *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
371 return ssl_open_record_error;
372 }
373
374 if (body.size() != 1 || body[0] != SSL3_MT_CCS) {
375 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
376 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
377 return ssl_open_record_error;
378 }
379
380 ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, body);
381 return ssl_open_record_success;
382 }
383
ssl_send_alert(SSL * ssl,int level,int desc)384 void ssl_send_alert(SSL *ssl, int level, int desc) {
385 // This function is called in response to a fatal error from the peer. Ignore
386 // any failures writing the alert and report only the original error. In
387 // particular, if the transport uses |SSL_write|, our existing error will be
388 // clobbered so we must save and restore the error queue. See
389 // https://crbug.com/959305.
390 //
391 // TODO(davidben): Return the alert out of the handshake, rather than calling
392 // this function internally everywhere.
393 //
394 // TODO(davidben): This does not allow retrying if the alert hit EAGAIN. See
395 // https://crbug.com/boringssl/130.
396 UniquePtr<ERR_SAVE_STATE> err_state(ERR_save_state());
397 ssl_send_alert_impl(ssl, level, desc);
398 ERR_restore_state(err_state.get());
399 }
400
ssl_send_alert_impl(SSL * ssl,int level,int desc)401 int ssl_send_alert_impl(SSL *ssl, int level, int desc) {
402 // It is illegal to send an alert when we've already sent a closing one.
403 if (ssl->s3->write_shutdown != ssl_shutdown_none) {
404 OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
405 return -1;
406 }
407
408 if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) {
409 ssl->s3->write_shutdown = ssl_shutdown_close_notify;
410 } else {
411 assert(level == SSL3_AL_FATAL);
412 assert(desc != SSL_AD_CLOSE_NOTIFY);
413 ssl->s3->write_shutdown = ssl_shutdown_error;
414 }
415
416 ssl->s3->alert_dispatch = true;
417 ssl->s3->send_alert[0] = level;
418 ssl->s3->send_alert[1] = desc;
419 if (ssl->s3->write_buffer.empty()) {
420 // Nothing is being written out, so the alert may be dispatched
421 // immediately.
422 return ssl->method->dispatch_alert(ssl);
423 }
424
425 // The alert will be dispatched later.
426 return -1;
427 }
428
tls_dispatch_alert(SSL * ssl)429 int tls_dispatch_alert(SSL *ssl) {
430 if (ssl->quic_method) {
431 if (!ssl->quic_method->send_alert(ssl, ssl->s3->write_level,
432 ssl->s3->send_alert[1])) {
433 OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
434 return 0;
435 }
436 } else {
437 int ret = do_tls_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
438 if (ret <= 0) {
439 return ret;
440 }
441 }
442
443 ssl->s3->alert_dispatch = false;
444
445 // If the alert is fatal, flush the BIO now.
446 if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
447 BIO_flush(ssl->wbio.get());
448 }
449
450 ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert);
451
452 int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
453 ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert);
454
455 return 1;
456 }
457
458 BSSL_NAMESPACE_END
459