1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * All rights reserved. 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This package is an SSL implementation written 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * by Eric Young (eay@cryptsoft.com). 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The implementation was written so as to conform with Netscapes SSL. 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This library is free for commercial and non-commercial use as long as 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the following conditions are aheared to. The following conditions 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * apply to all code found in this distribution, be it the RC4, RSA, 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * included with this distribution is covered by the same copyright terms 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the code are not to be removed. 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If this package is used in a product, Eric Young should be given attribution 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * as the author of the parts of the library used. 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This can be in the form of a textual message at program startup or 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * in documentation (online or textual) provided with the package. 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the copyright 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in the 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * documentation and/or other materials provided with the distribution. 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this software 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * must display the following acknowledgement: 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes cryptographic software written by 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Eric Young (eay@cryptsoft.com)" 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The word 'cryptographic' can be left out if the rouines from the library 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * being used are not cryptographic related :-). 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the apps directory (application code) you must include an acknowledgement: 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUCH DAMAGE. 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The licence and distribution terms for any publically available version or 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copied and put under another distribution licence 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * [including the GNU Public Licence.] 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the documentation and/or other materials provided with the 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distribution. 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * software must display the following acknowledgment: 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * endorse or promote products derived from this software without 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * prior written permission. For written permission, please contact 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * openssl-core@openssl.org. 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL" 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * nor may "OpenSSL" appear in their names without prior written 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * permission of the OpenSSL Project. 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * acknowledgment: 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com). This product includes software written by Tim 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */ 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 109b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/ssl.h> 110b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <assert.h> 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <limits.h> 113e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <string.h> 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/buf.h> 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/evp.h> 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h> 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/rand.h> 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 12169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan#include "../crypto/internal.h" 122e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "internal.h" 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1254139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleystatic int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len); 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 127b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root/* ssl3_get_record reads a new input record. On success, it places it in 128b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if 129b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root * more data is needed. */ 130b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootstatic int ssl3_get_record(SSL *ssl) { 131b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootagain: 132d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin switch (ssl->s3->recv_shutdown) { 133d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin case ssl_shutdown_none: 134d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin break; 135d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin case ssl_shutdown_fatal_alert: 136d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); 137d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin return -1; 138d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin case ssl_shutdown_close_notify: 139d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin return 0; 140d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin } 141d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin 1426e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin CBS body; 1435d625781eb8ff5cc8111d2302efe900103bf0adeRobert Sloan uint8_t type, alert = SSL_AD_DECODE_ERROR; 1446e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin size_t consumed; 1456e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin enum ssl_open_record_t open_ret = 1466e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin tls_open_record(ssl, &type, &body, &consumed, &alert, 1476e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin ssl_read_buffer(ssl), ssl_read_buffer_len(ssl)); 1486e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin if (open_ret != ssl_open_record_partial) { 1496e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin ssl_read_buffer_consume(ssl, consumed); 150b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root } 1516e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin switch (open_ret) { 1526e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin case ssl_open_record_partial: { 1536e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin int read_ret = ssl_read_buffer_extend_to(ssl, consumed); 1546e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin if (read_ret <= 0) { 1556e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin return read_ret; 1566e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin } 1576e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin goto again; 1586e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin } 159b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root 160b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root case ssl_open_record_success: 1616e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin if (CBS_len(&body) > 0xffff) { 162b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); 163b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root return -1; 164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 166b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root SSL3_RECORD *rr = &ssl->s3->rrec; 167b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root rr->type = type; 1686e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin rr->length = (uint16_t)CBS_len(&body); 1696e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin rr->data = (uint8_t *)CBS_data(&body); 170b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root return 1; 171b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root 172b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root case ssl_open_record_discard: 173b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root goto again; 174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1756e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin case ssl_open_record_close_notify: 1766e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin return 0; 1776e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin 1786e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin case ssl_open_record_fatal_alert: 1796e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin return -1; 1806e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin 181b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root case ssl_open_record_error: 182b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root ssl3_send_alert(ssl, SSL3_AL_FATAL, alert); 183b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root return -1; 184a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root } 185a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root 186b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root assert(0); 187b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); 188b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root return -1; 189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1914d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloanint ssl3_write_app_data(SSL *ssl, const uint8_t *buf, int len) { 1926d0d00e090b753250659b9a2d67dab7467257900Robert Sloan assert(ssl_can_write(ssl)); 1934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin unsigned tot, n, nw; 195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1964139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley assert(ssl->s3->wnum <= INT_MAX); 1974139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley tot = ssl->s3->wnum; 1984139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->wnum = 0; 199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Ensure that if we end up with a smaller value of data to write out than 201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the the original len from a write which didn't complete for non-blocking 202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * I/O and also somehow ended up avoiding the check for this in 203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be possible to 204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * end up with (len-tot) as a large number that will then promptly send 205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * beyond the end of the users buffer ... so we trap and report the error in 206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * a way the user will notice. */ 207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (len < 0 || (size_t)len < tot) { 208b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); 209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return -1; 210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2124d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan n = len - tot; 213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley for (;;) { 214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* max contains the maximum number of bytes that we can put into a 215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * record. */ 2164139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley unsigned max = ssl->max_send_fragment; 217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (n > max) { 218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley nw = max; 219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley nw = n; 221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2234d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan int ret = do_ssl3_write(ssl, SSL3_RT_APPLICATION_DATA, &buf[tot], nw); 2244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (ret <= 0) { 2254139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->wnum = tot; 2264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return ret; 227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2294d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan if (ret == (int)n || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { 2304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return tot + ret; 231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin n -= ret; 2344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tot += ret; 235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 236d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2384139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleystatic int ssl3_write_pending(SSL *ssl, int type, const uint8_t *buf, 239fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley unsigned int len) { 2404139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley if (ssl->s3->wpend_tot > (int)len || 241909b19f027eb0af12513f4d5589efdd67e34bd91Steven Valdez (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && 242909b19f027eb0af12513f4d5589efdd67e34bd91Steven Valdez ssl->s3->wpend_buf != buf) || 2434139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->wpend_type != type) { 244fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY); 245fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return -1; 246fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 247fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 2484139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley int ret = ssl_write_buffer_flush(ssl); 249fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ret <= 0) { 250fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return ret; 251fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 2524139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley return ssl->s3->wpend_ret; 253fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley} 254fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 255b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root/* do_ssl3_write writes an SSL record of the given type. */ 2564139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleystatic int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len) { 257b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root /* If there is still data from the previous record, flush it. */ 2584139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley if (ssl_write_buffer_is_pending(ssl)) { 2594139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley return ssl3_write_pending(ssl, type, buf, len); 260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2624d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan /* The handshake flight buffer is mutually exclusive with application data. 2634d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan * 2644d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan * TODO(davidben): This will not be true when closure alerts use this. */ 2654d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan if (ssl->s3->pending_flight != NULL) { 2664d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); 2674d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan return -1; 268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 270b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root if (len > SSL3_RT_MAX_PLAIN_LENGTH) { 271b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); 272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return -1; 273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 275d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (len == 0) { 276d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 277d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 279909b19f027eb0af12513f4d5589efdd67e34bd91Steven Valdez size_t max_out = len + SSL_max_seal_overhead(ssl); 280b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root if (max_out < len) { 281b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); 282b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root return -1; 283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 284b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root uint8_t *out; 285e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley size_t ciphertext_len; 2864139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley if (!ssl_write_buffer_init(ssl, &out, max_out) || 2874139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley !tls_seal_record(ssl, out, &ciphertext_len, max_out, type, buf, len)) { 288e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return -1; 289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 2904139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl_write_buffer_set_len(ssl, ciphertext_len); 291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* memorize arguments so that ssl3_write_pending can detect bad write retries 293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * later */ 2944139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->wpend_tot = len; 2954139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->wpend_buf = buf; 2964139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->wpend_type = type; 2974139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->wpend_ret = len; 298d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* we now just need to write the buffer */ 3004139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley return ssl3_write_pending(ssl, type, buf, len); 301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 303c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjaminstatic int consume_record(SSL *ssl, uint8_t *out, int len, int peek) { 304c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin SSL3_RECORD *rr = &ssl->s3->rrec; 305c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 306c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (len <= 0) { 307c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return len; 308c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 309c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 310c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (len > (int)rr->length) { 311c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin len = (int)rr->length; 312c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 313c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 31469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memcpy(out, rr->data, len); 315c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (!peek) { 316c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin rr->length -= len; 317c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin rr->data += len; 318c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (rr->length == 0) { 319c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin /* The record has been consumed, so we may now clear the buffer. */ 320c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin ssl_read_buffer_discard(ssl); 321c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 322c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 323c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return len; 324c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin} 325c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 326c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjaminint ssl3_read_app_data(SSL *ssl, int *out_got_handshake, uint8_t *buf, int len, 327c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin int peek) { 3286d0d00e090b753250659b9a2d67dab7467257900Robert Sloan assert(ssl_can_read(ssl)); 329c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin *out_got_handshake = 0; 330c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 3316d0d00e090b753250659b9a2d67dab7467257900Robert Sloan ssl->method->release_current_message(ssl, 0 /* don't free buffer */); 3326d0d00e090b753250659b9a2d67dab7467257900Robert Sloan 333c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin SSL3_RECORD *rr = &ssl->s3->rrec; 334c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 335c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin for (;;) { 336c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin /* A previous iteration may have read a partial handshake message. Do not 337c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin * allow more app data in that case. */ 338c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin int has_hs_data = ssl->init_buf != NULL && ssl->init_buf->length > 0; 339c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 340c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin /* Get new packet if necessary. */ 341c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (rr->length == 0 && !has_hs_data) { 342c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin int ret = ssl3_get_record(ssl); 343c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (ret <= 0) { 344c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return ret; 345c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 346c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 347c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 348c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (has_hs_data || rr->type == SSL3_RT_HANDSHAKE) { 3496d0d00e090b753250659b9a2d67dab7467257900Robert Sloan /* If reading 0-RTT data, reject handshake data. 0-RTT data is terminated 3506d0d00e090b753250659b9a2d67dab7467257900Robert Sloan * by an alert. */ 3516d0d00e090b753250659b9a2d67dab7467257900Robert Sloan if (SSL_in_init(ssl)) { 3526d0d00e090b753250659b9a2d67dab7467257900Robert Sloan OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); 3536d0d00e090b753250659b9a2d67dab7467257900Robert Sloan ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); 3546d0d00e090b753250659b9a2d67dab7467257900Robert Sloan return -1; 3556d0d00e090b753250659b9a2d67dab7467257900Robert Sloan } 3566d0d00e090b753250659b9a2d67dab7467257900Robert Sloan 357c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin /* Post-handshake data prior to TLS 1.3 is always renegotiation, which we 358c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin * never accept as a server. Otherwise |ssl3_get_message| will send 359c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin * |SSL_R_EXCESSIVE_MESSAGE_SIZE|. */ 360c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (ssl->server && ssl3_protocol_version(ssl) < TLS1_3_VERSION) { 361c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); 362c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); 363c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return -1; 364c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 3656e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin 366c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin /* Parse post-handshake handshake messages. */ 3674d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan int ret = ssl3_get_message(ssl); 368c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (ret <= 0) { 369c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return ret; 370c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 371c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin *out_got_handshake = 1; 372c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return -1; 373c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 374c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 3756d0d00e090b753250659b9a2d67dab7467257900Robert Sloan /* Handle the end_of_early_data alert. */ 3766d0d00e090b753250659b9a2d67dab7467257900Robert Sloan if (rr->type == SSL3_RT_ALERT && 3776d0d00e090b753250659b9a2d67dab7467257900Robert Sloan rr->length == 2 && 3786d0d00e090b753250659b9a2d67dab7467257900Robert Sloan rr->data[0] == SSL3_AL_WARNING && 3796d0d00e090b753250659b9a2d67dab7467257900Robert Sloan rr->data[1] == TLS1_AD_END_OF_EARLY_DATA && 3806d0d00e090b753250659b9a2d67dab7467257900Robert Sloan ssl->server && 3816d0d00e090b753250659b9a2d67dab7467257900Robert Sloan ssl->s3->hs != NULL && 3826d0d00e090b753250659b9a2d67dab7467257900Robert Sloan ssl->s3->hs->can_early_read && 3836d0d00e090b753250659b9a2d67dab7467257900Robert Sloan ssl3_protocol_version(ssl) >= TLS1_3_VERSION) { 3846d0d00e090b753250659b9a2d67dab7467257900Robert Sloan /* Consume the record. */ 3856d0d00e090b753250659b9a2d67dab7467257900Robert Sloan rr->length = 0; 3866d0d00e090b753250659b9a2d67dab7467257900Robert Sloan ssl_read_buffer_discard(ssl); 3876d0d00e090b753250659b9a2d67dab7467257900Robert Sloan /* Stop accepting early data. */ 3886d0d00e090b753250659b9a2d67dab7467257900Robert Sloan ssl->s3->hs->can_early_read = 0; 3896d0d00e090b753250659b9a2d67dab7467257900Robert Sloan *out_got_handshake = 1; 3906d0d00e090b753250659b9a2d67dab7467257900Robert Sloan return -1; 3916d0d00e090b753250659b9a2d67dab7467257900Robert Sloan } 3926d0d00e090b753250659b9a2d67dab7467257900Robert Sloan 393c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (rr->type != SSL3_RT_APPLICATION_DATA) { 394c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); 395c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); 396c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return -1; 397c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 398c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 399c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (rr->length != 0) { 400c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return consume_record(ssl, buf, len, peek); 401c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 402c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 403c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin /* Discard empty records and loop again. */ 404c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 4054139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley} 4064139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley 4074139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint ssl3_read_change_cipher_spec(SSL *ssl) { 4086e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin SSL3_RECORD *rr = &ssl->s3->rrec; 4096e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin 4106e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin if (rr->length == 0) { 4116e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin int ret = ssl3_get_record(ssl); 4126e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin if (ret <= 0) { 4136e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin return ret; 4146e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin } 415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4176e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) { 4186e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); 4196e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); 4206e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin return -1; 4216e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin } 4226e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin 4236e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin if (rr->length != 1 || rr->data[0] != SSL3_MT_CCS) { 4244139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); 4254139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); 4264139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley return -1; 4274139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley } 428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4297c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 4307c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin rr->length); 4314139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley 4326e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin rr->length = 0; 4336e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin ssl_read_buffer_discard(ssl); 4344139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley return 1; 435f4e427204234da139fd0585def4b4e22502e33f0Adam Langley} 436f4e427204234da139fd0585def4b4e22502e33f0Adam Langley 437f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyvoid ssl3_read_close_notify(SSL *ssl) { 4386e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin /* Read records until an error or close_notify. */ 4396e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin while (ssl3_get_record(ssl) > 0) { 4406e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin ; 4416e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin } 442f4e427204234da139fd0585def4b4e22502e33f0Adam Langley} 443f4e427204234da139fd0585def4b4e22502e33f0Adam Langley 444c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjaminint ssl3_read_handshake_bytes(SSL *ssl, uint8_t *buf, int len) { 445c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin SSL3_RECORD *rr = &ssl->s3->rrec; 446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 447c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin for (;;) { 448c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin /* Get new packet if necessary. */ 449b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root if (rr->length == 0) { 450c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin int ret = ssl3_get_record(ssl); 451c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (ret <= 0) { 452c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return ret; 4534139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley } 454d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 456c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (rr->type != SSL3_RT_HANDSHAKE) { 457c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); 458c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); 459c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return -1; 460f4e427204234da139fd0585def4b4e22502e33f0Adam Langley } 461f4e427204234da139fd0585def4b4e22502e33f0Adam Langley 462c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (rr->length != 0) { 463c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return consume_record(ssl, buf, len, 0 /* consume data */); 464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 465f4e427204234da139fd0585def4b4e22502e33f0Adam Langley 466c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin /* Discard empty records and loop again. */ 467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4704139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint ssl3_send_alert(SSL *ssl, int level, int desc) { 471d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin /* It is illegal to send an alert when we've already sent a closing one. */ 472d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin if (ssl->s3->send_shutdown != ssl_shutdown_none) { 473d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); 474d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin return -1; 475d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin } 476d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin 4774d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) { 478d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin ssl->s3->send_shutdown = ssl_shutdown_close_notify; 4794d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan } else { 4804d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan assert(level == SSL3_AL_FATAL); 4814d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan ssl->s3->send_shutdown = ssl_shutdown_fatal_alert; 482d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 483d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4844139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->alert_dispatch = 1; 4854139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->send_alert[0] = level; 4864139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley ssl->s3->send_alert[1] = desc; 4874139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley if (!ssl_write_buffer_is_pending(ssl)) { 488b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root /* Nothing is being written out, so the alert may be dispatched 489b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root * immediately. */ 490c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return ssl->method->dispatch_alert(ssl); 491d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 492d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 493d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin /* The alert will be dispatched later. */ 494d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return -1; 495d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 496d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4974139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint ssl3_dispatch_alert(SSL *ssl) { 4984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2); 4994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (ret <= 0) { 5004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return ret; 5014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 5024d1ac508237e73d6596202e4fa36d93ecf2321d8Robert Sloan ssl->s3->alert_dispatch = 0; 503d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 5044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If the alert is fatal, flush the BIO now. */ 5054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { 5064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_flush(ssl->wbio); 5074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 508d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 5097c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert, 5107c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin 2); 511d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 5126e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; 5136e899c7d3f4c7bd6383a0ca171a50e95aa9d8e2dDavid Benjamin ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); 514d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 5154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 516d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 517