1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 (at) 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 (at) cryptsoft.com). This product includes software written by Tim 107 * Hudson (tjh (at) 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/buf.h> 116 #include <openssl/err.h> 117 #include <openssl/evp.h> 118 #include <openssl/mem.h> 119 #include <openssl/rand.h> 120 121 #include "../crypto/internal.h" 122 #include "internal.h" 123 124 125 namespace bssl { 126 127 static int do_ssl3_write(SSL *ssl, int type, const uint8_t *in, unsigned len); 128 129 int ssl3_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 // ssl3_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 && max > ssl->session->ticket_max_early_data - 167 ssl->s3->hs->early_data_written) { 168 max = ssl->session->ticket_max_early_data - ssl->s3->hs->early_data_written; 169 if (max == 0) { 170 ssl->s3->wnum = tot; 171 ssl->s3->hs->can_early_write = false; 172 *out_needs_handshake = true; 173 return -1; 174 } 175 } 176 177 if (n > max) { 178 nw = max; 179 } else { 180 nw = n; 181 } 182 183 int ret = do_ssl3_write(ssl, SSL3_RT_APPLICATION_DATA, &in[tot], nw); 184 if (ret <= 0) { 185 ssl->s3->wnum = tot; 186 return ret; 187 } 188 189 if (is_early_data_write) { 190 ssl->s3->hs->early_data_written += ret; 191 } 192 193 if (ret == (int)n || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { 194 return tot + ret; 195 } 196 197 n -= ret; 198 tot += ret; 199 } 200 } 201 202 static int ssl3_write_pending(SSL *ssl, int type, const uint8_t *in, 203 unsigned int len) { 204 if (ssl->s3->wpend_tot > (int)len || 205 (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && 206 ssl->s3->wpend_buf != in) || 207 ssl->s3->wpend_type != type) { 208 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY); 209 return -1; 210 } 211 212 int ret = ssl_write_buffer_flush(ssl); 213 if (ret <= 0) { 214 return ret; 215 } 216 ssl->s3->wpend_pending = false; 217 return ssl->s3->wpend_ret; 218 } 219 220 // do_ssl3_write writes an SSL record of the given type. 221 static int do_ssl3_write(SSL *ssl, int type, const uint8_t *in, unsigned len) { 222 // If there is still data from the previous record, flush it. 223 if (ssl->s3->wpend_pending) { 224 return ssl3_write_pending(ssl, type, in, len); 225 } 226 227 SSLBuffer *buf = &ssl->s3->write_buffer; 228 if (len > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) { 229 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); 230 return -1; 231 } 232 233 if (len == 0) { 234 return 0; 235 } 236 237 size_t flight_len = 0; 238 if (ssl->s3->pending_flight != nullptr) { 239 flight_len = 240 ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset; 241 } 242 243 size_t max_out = len + SSL_max_seal_overhead(ssl); 244 if (max_out < len || max_out + flight_len < max_out) { 245 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); 246 return -1; 247 } 248 max_out += flight_len; 249 250 if (!buf->EnsureCap(flight_len + ssl_seal_align_prefix_len(ssl), max_out)) { 251 return -1; 252 } 253 254 // Add any unflushed handshake data as a prefix. This may be a KeyUpdate 255 // acknowledgment or 0-RTT key change messages. |pending_flight| must be clear 256 // when data is added to |write_buffer| or it will be written in the wrong 257 // order. 258 if (ssl->s3->pending_flight != nullptr) { 259 OPENSSL_memcpy( 260 buf->remaining().data(), 261 ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, 262 flight_len); 263 ssl->s3->pending_flight.reset(); 264 ssl->s3->pending_flight_offset = 0; 265 buf->DidWrite(flight_len); 266 } 267 268 size_t ciphertext_len; 269 if (!tls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, 270 buf->remaining().size(), type, in, len)) { 271 return -1; 272 } 273 buf->DidWrite(ciphertext_len); 274 275 // Now that we've made progress on the connection, uncork KeyUpdate 276 // acknowledgments. 277 ssl->s3->key_update_pending = false; 278 279 // Memorize arguments so that ssl3_write_pending can detect bad write retries 280 // later. 281 ssl->s3->wpend_tot = len; 282 ssl->s3->wpend_buf = in; 283 ssl->s3->wpend_type = type; 284 ssl->s3->wpend_ret = len; 285 ssl->s3->wpend_pending = true; 286 287 // We now just need to write the buffer. 288 return ssl3_write_pending(ssl, type, in, len); 289 } 290 291 ssl_open_record_t ssl3_open_app_data(SSL *ssl, Span<uint8_t> *out, 292 size_t *out_consumed, uint8_t *out_alert, 293 Span<uint8_t> in) { 294 assert(ssl_can_read(ssl)); 295 assert(!ssl->s3->aead_read_ctx->is_null_cipher()); 296 297 uint8_t type; 298 Span<uint8_t> body; 299 auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); 300 if (ret != ssl_open_record_success) { 301 return ret; 302 } 303 304 const bool is_early_data_read = ssl->server && SSL_in_early_data(ssl); 305 306 if (type == SSL3_RT_HANDSHAKE) { 307 // Post-handshake data prior to TLS 1.3 is always renegotiation, which we 308 // never accept as a server. Otherwise |ssl3_get_message| will send 309 // |SSL_R_EXCESSIVE_MESSAGE_SIZE|. 310 if (ssl->server && ssl_protocol_version(ssl) < TLS1_3_VERSION) { 311 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); 312 *out_alert = SSL_AD_NO_RENEGOTIATION; 313 return ssl_open_record_error; 314 } 315 316 if (!ssl->s3->hs_buf) { 317 ssl->s3->hs_buf.reset(BUF_MEM_new()); 318 } 319 if (!ssl->s3->hs_buf || 320 !BUF_MEM_append(ssl->s3->hs_buf.get(), body.data(), body.size())) { 321 *out_alert = SSL_AD_INTERNAL_ERROR; 322 return ssl_open_record_error; 323 } 324 return ssl_open_record_discard; 325 } 326 327 if (type != SSL3_RT_APPLICATION_DATA) { 328 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); 329 *out_alert = SSL_AD_UNEXPECTED_MESSAGE; 330 return ssl_open_record_error; 331 } 332 333 if (is_early_data_read) { 334 if (body.size() > kMaxEarlyDataAccepted - ssl->s3->hs->early_data_read) { 335 OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_READ_EARLY_DATA); 336 *out_alert = SSL3_AD_UNEXPECTED_MESSAGE; 337 return ssl_open_record_error; 338 } 339 340 ssl->s3->hs->early_data_read += body.size(); 341 } 342 343 if (body.empty()) { 344 return ssl_open_record_discard; 345 } 346 347 *out = body; 348 return ssl_open_record_success; 349 } 350 351 ssl_open_record_t ssl3_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, 352 uint8_t *out_alert, 353 Span<uint8_t> in) { 354 uint8_t type; 355 Span<uint8_t> body; 356 auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); 357 if (ret != ssl_open_record_success) { 358 return ret; 359 } 360 361 if (type != SSL3_RT_CHANGE_CIPHER_SPEC) { 362 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); 363 *out_alert = SSL_AD_UNEXPECTED_MESSAGE; 364 return ssl_open_record_error; 365 } 366 367 if (body.size() != 1 || body[0] != SSL3_MT_CCS) { 368 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); 369 *out_alert = SSL_AD_ILLEGAL_PARAMETER; 370 return ssl_open_record_error; 371 } 372 373 ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, body); 374 return ssl_open_record_success; 375 } 376 377 int ssl_send_alert(SSL *ssl, int level, int desc) { 378 // It is illegal to send an alert when we've already sent a closing one. 379 if (ssl->s3->write_shutdown != ssl_shutdown_none) { 380 OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); 381 return -1; 382 } 383 384 if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) { 385 ssl->s3->write_shutdown = ssl_shutdown_close_notify; 386 } else { 387 assert(level == SSL3_AL_FATAL); 388 assert(desc != SSL_AD_CLOSE_NOTIFY); 389 ssl->s3->write_shutdown = ssl_shutdown_error; 390 } 391 392 ssl->s3->alert_dispatch = 1; 393 ssl->s3->send_alert[0] = level; 394 ssl->s3->send_alert[1] = desc; 395 if (ssl->s3->write_buffer.empty()) { 396 // Nothing is being written out, so the alert may be dispatched 397 // immediately. 398 return ssl->method->dispatch_alert(ssl); 399 } 400 401 // The alert will be dispatched later. 402 return -1; 403 } 404 405 int ssl3_dispatch_alert(SSL *ssl) { 406 int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2); 407 if (ret <= 0) { 408 return ret; 409 } 410 ssl->s3->alert_dispatch = 0; 411 412 // If the alert is fatal, flush the BIO now. 413 if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { 414 BIO_flush(ssl->wbio); 415 } 416 417 ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); 418 419 int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; 420 ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); 421 422 return 1; 423 } 424 425 } // namespace bssl 426