1*f4fe6251Sjsing /* $OpenBSD: ssl_pkt.c,v 1.68 2024/07/22 14:47:15 jsing Exp $ */ 23395f70eSjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 33395f70eSjsing * All rights reserved. 43395f70eSjsing * 53395f70eSjsing * This package is an SSL implementation written 63395f70eSjsing * by Eric Young (eay@cryptsoft.com). 73395f70eSjsing * The implementation was written so as to conform with Netscapes SSL. 83395f70eSjsing * 93395f70eSjsing * This library is free for commercial and non-commercial use as long as 103395f70eSjsing * the following conditions are aheared to. The following conditions 113395f70eSjsing * apply to all code found in this distribution, be it the RC4, RSA, 123395f70eSjsing * lhash, DES, etc., code; not just the SSL code. The SSL documentation 133395f70eSjsing * included with this distribution is covered by the same copyright terms 143395f70eSjsing * except that the holder is Tim Hudson (tjh@cryptsoft.com). 153395f70eSjsing * 163395f70eSjsing * Copyright remains Eric Young's, and as such any Copyright notices in 173395f70eSjsing * the code are not to be removed. 183395f70eSjsing * If this package is used in a product, Eric Young should be given attribution 193395f70eSjsing * as the author of the parts of the library used. 203395f70eSjsing * This can be in the form of a textual message at program startup or 213395f70eSjsing * in documentation (online or textual) provided with the package. 223395f70eSjsing * 233395f70eSjsing * Redistribution and use in source and binary forms, with or without 243395f70eSjsing * modification, are permitted provided that the following conditions 253395f70eSjsing * are met: 263395f70eSjsing * 1. Redistributions of source code must retain the copyright 273395f70eSjsing * notice, this list of conditions and the following disclaimer. 283395f70eSjsing * 2. Redistributions in binary form must reproduce the above copyright 293395f70eSjsing * notice, this list of conditions and the following disclaimer in the 303395f70eSjsing * documentation and/or other materials provided with the distribution. 313395f70eSjsing * 3. All advertising materials mentioning features or use of this software 323395f70eSjsing * must display the following acknowledgement: 333395f70eSjsing * "This product includes cryptographic software written by 343395f70eSjsing * Eric Young (eay@cryptsoft.com)" 353395f70eSjsing * The word 'cryptographic' can be left out if the rouines from the library 363395f70eSjsing * being used are not cryptographic related :-). 373395f70eSjsing * 4. If you include any Windows specific code (or a derivative thereof) from 383395f70eSjsing * the apps directory (application code) you must include an acknowledgement: 393395f70eSjsing * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 403395f70eSjsing * 413395f70eSjsing * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 423395f70eSjsing * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 433395f70eSjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 443395f70eSjsing * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 453395f70eSjsing * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 463395f70eSjsing * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 473395f70eSjsing * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 483395f70eSjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 493395f70eSjsing * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 503395f70eSjsing * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 513395f70eSjsing * SUCH DAMAGE. 523395f70eSjsing * 533395f70eSjsing * The licence and distribution terms for any publically available version or 543395f70eSjsing * derivative of this code cannot be changed. i.e. this code cannot simply be 553395f70eSjsing * copied and put under another distribution licence 563395f70eSjsing * [including the GNU Public Licence.] 573395f70eSjsing */ 583395f70eSjsing /* ==================================================================== 593395f70eSjsing * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 603395f70eSjsing * 613395f70eSjsing * Redistribution and use in source and binary forms, with or without 623395f70eSjsing * modification, are permitted provided that the following conditions 633395f70eSjsing * are met: 643395f70eSjsing * 653395f70eSjsing * 1. Redistributions of source code must retain the above copyright 663395f70eSjsing * notice, this list of conditions and the following disclaimer. 673395f70eSjsing * 683395f70eSjsing * 2. Redistributions in binary form must reproduce the above copyright 693395f70eSjsing * notice, this list of conditions and the following disclaimer in 703395f70eSjsing * the documentation and/or other materials provided with the 713395f70eSjsing * distribution. 723395f70eSjsing * 733395f70eSjsing * 3. All advertising materials mentioning features or use of this 743395f70eSjsing * software must display the following acknowledgment: 753395f70eSjsing * "This product includes software developed by the OpenSSL Project 763395f70eSjsing * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 773395f70eSjsing * 783395f70eSjsing * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 793395f70eSjsing * endorse or promote products derived from this software without 803395f70eSjsing * prior written permission. For written permission, please contact 813395f70eSjsing * openssl-core@openssl.org. 823395f70eSjsing * 833395f70eSjsing * 5. Products derived from this software may not be called "OpenSSL" 843395f70eSjsing * nor may "OpenSSL" appear in their names without prior written 853395f70eSjsing * permission of the OpenSSL Project. 863395f70eSjsing * 873395f70eSjsing * 6. Redistributions of any form whatsoever must retain the following 883395f70eSjsing * acknowledgment: 893395f70eSjsing * "This product includes software developed by the OpenSSL Project 903395f70eSjsing * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 913395f70eSjsing * 923395f70eSjsing * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 933395f70eSjsing * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 943395f70eSjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 953395f70eSjsing * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 963395f70eSjsing * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 973395f70eSjsing * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 983395f70eSjsing * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 993395f70eSjsing * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1003395f70eSjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 1013395f70eSjsing * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1023395f70eSjsing * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1033395f70eSjsing * OF THE POSSIBILITY OF SUCH DAMAGE. 1043395f70eSjsing * ==================================================================== 1053395f70eSjsing * 1063395f70eSjsing * This product includes cryptographic software written by Eric Young 1073395f70eSjsing * (eay@cryptsoft.com). This product includes software written by Tim 1083395f70eSjsing * Hudson (tjh@cryptsoft.com). 1093395f70eSjsing * 1103395f70eSjsing */ 1113395f70eSjsing 1123395f70eSjsing #include <errno.h> 113ee4250f6Sjsing #include <limits.h> 1143395f70eSjsing #include <stdio.h> 1153395f70eSjsing 1163395f70eSjsing #include <openssl/buffer.h> 1173395f70eSjsing #include <openssl/evp.h> 1183395f70eSjsing 1193395f70eSjsing #include "bytestring.h" 120c9675a23Stb #include "dtls_local.h" 121c9675a23Stb #include "ssl_local.h" 122ee4250f6Sjsing #include "tls_content.h" 1233395f70eSjsing 1243395f70eSjsing static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, 125f91e30d7Sjsing unsigned int len); 1263395f70eSjsing static int ssl3_get_record(SSL *s); 1273395f70eSjsing 128a2584b01Sbeck /* 129a2584b01Sbeck * Force a WANT_READ return for certain error conditions where 130a2584b01Sbeck * we don't want to spin internally. 131a2584b01Sbeck */ 132e2a9b682Sjsing void 133a2584b01Sbeck ssl_force_want_read(SSL *s) 134a2584b01Sbeck { 135a2584b01Sbeck BIO *bio; 136a2584b01Sbeck 137a2584b01Sbeck bio = SSL_get_rbio(s); 138a2584b01Sbeck BIO_clear_retry_flags(bio); 139a2584b01Sbeck BIO_set_retry_read(bio); 140e2a9b682Sjsing 1416f7f653bSjsing s->rwstate = SSL_READING; 142a2584b01Sbeck } 143a2584b01Sbeck 144301623b9Sjsing /* 145301623b9Sjsing * If extend == 0, obtain new n-byte packet; if extend == 1, increase 146301623b9Sjsing * packet by another n bytes. 14702876cc3Sjsing * The packet will be in the sub-array of s->s3->rbuf.buf specified 1486f7f653bSjsing * by s->packet and s->packet_length. 1496f7f653bSjsing * (If s->read_ahead is set, 'max' bytes may be stored in rbuf 1506f7f653bSjsing * [plus s->packet_length bytes if extend == 1].) 151301623b9Sjsing */ 1523395f70eSjsing static int 1533395f70eSjsing ssl3_read_n(SSL *s, int n, int max, int extend) 1543395f70eSjsing { 15502876cc3Sjsing SSL3_BUFFER_INTERNAL *rb = &(s->s3->rbuf); 1563395f70eSjsing int i, len, left; 1573395f70eSjsing size_t align; 1583395f70eSjsing unsigned char *pkt; 1593395f70eSjsing 1603395f70eSjsing if (n <= 0) 1613395f70eSjsing return n; 1623395f70eSjsing 163dfea2de7Stb if (rb->buf == NULL) { 1643395f70eSjsing if (!ssl3_setup_read_buffer(s)) 1653395f70eSjsing return -1; 166dfea2de7Stb } 167dfea2de7Stb if (rb->buf == NULL) 168dfea2de7Stb return -1; 1693395f70eSjsing 1703395f70eSjsing left = rb->left; 1713395f70eSjsing align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH; 1723395f70eSjsing align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); 1733395f70eSjsing 1743395f70eSjsing if (!extend) { 1753395f70eSjsing /* start with empty packet ... */ 1763395f70eSjsing if (left == 0) 1773395f70eSjsing rb->offset = align; 1783395f70eSjsing else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { 1793395f70eSjsing /* check if next packet length is large 1803395f70eSjsing * enough to justify payload alignment... */ 1813395f70eSjsing pkt = rb->buf + rb->offset; 1823395f70eSjsing if (pkt[0] == SSL3_RT_APPLICATION_DATA && 1833395f70eSjsing (pkt[3]<<8|pkt[4]) >= 128) { 1843395f70eSjsing /* Note that even if packet is corrupted 1853395f70eSjsing * and its length field is insane, we can 1863395f70eSjsing * only be led to wrong decision about 1873395f70eSjsing * whether memmove will occur or not. 1883395f70eSjsing * Header values has no effect on memmove 1893395f70eSjsing * arguments and therefore no buffer 1903395f70eSjsing * overrun can be triggered. */ 1913395f70eSjsing memmove(rb->buf + align, pkt, left); 1923395f70eSjsing rb->offset = align; 1933395f70eSjsing } 1943395f70eSjsing } 1956f7f653bSjsing s->packet = rb->buf + rb->offset; 1966f7f653bSjsing s->packet_length = 0; 1973395f70eSjsing /* ... now we can act as if 'extend' was set */ 1983395f70eSjsing } 1993395f70eSjsing 2003395f70eSjsing /* For DTLS/UDP reads should not span multiple packets 2013395f70eSjsing * because the read operation returns the whole packet 2023395f70eSjsing * at once (as long as it fits into the buffer). */ 2039e659261Sjsing if (SSL_is_dtls(s)) { 2043395f70eSjsing if (left > 0 && n > left) 2053395f70eSjsing n = left; 2063395f70eSjsing } 2073395f70eSjsing 2083395f70eSjsing /* if there is enough in the buffer from a previous read, take some */ 2093395f70eSjsing if (left >= n) { 2106f7f653bSjsing s->packet_length += n; 2113395f70eSjsing rb->left = left - n; 2123395f70eSjsing rb->offset += n; 2133395f70eSjsing return (n); 2143395f70eSjsing } 2153395f70eSjsing 2163395f70eSjsing /* else we need to read more data */ 2173395f70eSjsing 2186f7f653bSjsing len = s->packet_length; 2193395f70eSjsing pkt = rb->buf + align; 2203395f70eSjsing /* Move any available bytes to front of buffer: 2213395f70eSjsing * 'len' bytes already pointed to by 'packet', 2223395f70eSjsing * 'left' extra ones at the end */ 2236f7f653bSjsing if (s->packet != pkt) { 2243395f70eSjsing /* len > 0 */ 2256f7f653bSjsing memmove(pkt, s->packet, len + left); 2266f7f653bSjsing s->packet = pkt; 2273395f70eSjsing rb->offset = len + align; 2283395f70eSjsing } 2293395f70eSjsing 2303395f70eSjsing if (n > (int)(rb->len - rb->offset)) { 2313395f70eSjsing /* does not happen */ 232c9d7abb7Sbeck SSLerror(s, ERR_R_INTERNAL_ERROR); 2333395f70eSjsing return -1; 2343395f70eSjsing } 2353395f70eSjsing 2366f7f653bSjsing if (s->read_ahead || SSL_is_dtls(s)) { 2373395f70eSjsing if (max < n) 2383395f70eSjsing max = n; 2393395f70eSjsing if (max > (int)(rb->len - rb->offset)) 2403395f70eSjsing max = rb->len - rb->offset; 24150c78444Sjsing } else { 24250c78444Sjsing /* ignore max parameter */ 24350c78444Sjsing max = n; 2443395f70eSjsing } 2453395f70eSjsing 2463395f70eSjsing while (left < n) { 24702876cc3Sjsing /* Now we have len+left bytes at the front of s->s3->rbuf.buf 2483395f70eSjsing * and need to read in more until we have len+n (up to 2493395f70eSjsing * len+max if possible) */ 2503395f70eSjsing 2513395f70eSjsing errno = 0; 2523395f70eSjsing if (s->rbio != NULL) { 2536f7f653bSjsing s->rwstate = SSL_READING; 2543395f70eSjsing i = BIO_read(s->rbio, pkt + len + left, max - left); 2553395f70eSjsing } else { 256c9d7abb7Sbeck SSLerror(s, SSL_R_READ_BIO_NOT_SET); 2573395f70eSjsing i = -1; 2583395f70eSjsing } 2593395f70eSjsing 2603395f70eSjsing if (i <= 0) { 2613395f70eSjsing rb->left = left; 2626f7f653bSjsing if (s->mode & SSL_MODE_RELEASE_BUFFERS && 2639e659261Sjsing !SSL_is_dtls(s)) { 2643395f70eSjsing if (len + left == 0) 2653395f70eSjsing ssl3_release_read_buffer(s); 2663395f70eSjsing } 2673395f70eSjsing return (i); 2683395f70eSjsing } 2693395f70eSjsing left += i; 2703395f70eSjsing 2713395f70eSjsing /* 2723395f70eSjsing * reads should *never* span multiple packets for DTLS because 2733395f70eSjsing * the underlying transport protocol is message oriented as 2743395f70eSjsing * opposed to byte oriented as in the TLS case. 2753395f70eSjsing */ 2769e659261Sjsing if (SSL_is_dtls(s)) { 2773395f70eSjsing if (n > left) 2783395f70eSjsing n = left; /* makes the while condition false */ 2793395f70eSjsing } 2803395f70eSjsing } 2813395f70eSjsing 2823395f70eSjsing /* done reading, now the book-keeping */ 2833395f70eSjsing rb->offset += n; 2843395f70eSjsing rb->left = left - n; 2856f7f653bSjsing s->packet_length += n; 2866f7f653bSjsing s->rwstate = SSL_NOTHING; 2873395f70eSjsing 2883395f70eSjsing return (n); 2893395f70eSjsing } 2903395f70eSjsing 2913395f70eSjsing int 2923395f70eSjsing ssl3_packet_read(SSL *s, int plen) 2933395f70eSjsing { 2943395f70eSjsing int n; 2953395f70eSjsing 29602876cc3Sjsing n = ssl3_read_n(s, plen, s->s3->rbuf.len, 0); 2973395f70eSjsing if (n <= 0) 2983395f70eSjsing return n; 2996f7f653bSjsing if (s->packet_length < plen) 3006f7f653bSjsing return s->packet_length; 3013395f70eSjsing 3023395f70eSjsing return plen; 3033395f70eSjsing } 3043395f70eSjsing 3053395f70eSjsing int 3063395f70eSjsing ssl3_packet_extend(SSL *s, int plen) 3073395f70eSjsing { 3083395f70eSjsing int rlen, n; 3093395f70eSjsing 3106f7f653bSjsing if (s->packet_length >= plen) 3113395f70eSjsing return plen; 3126f7f653bSjsing rlen = plen - s->packet_length; 3133395f70eSjsing 3143395f70eSjsing n = ssl3_read_n(s, rlen, rlen, 1); 3153395f70eSjsing if (n <= 0) 3163395f70eSjsing return n; 3176f7f653bSjsing if (s->packet_length < plen) 3186f7f653bSjsing return s->packet_length; 3193395f70eSjsing 3203395f70eSjsing return plen; 3213395f70eSjsing } 3223395f70eSjsing 3233395f70eSjsing /* Call this to get a new input record. 3243395f70eSjsing * It will return <= 0 if more data is needed, normally due to an error 3253395f70eSjsing * or non-blocking IO. 3263395f70eSjsing * When it finishes, one packet has been decoded and can be found in 3276f7f653bSjsing * ssl->s3->rrec.type - is the type of record 3286f7f653bSjsing * ssl->s3->rrec.data, - data 3296f7f653bSjsing * ssl->s3->rrec.length, - number of bytes 3303395f70eSjsing */ 3313395f70eSjsing /* used only by ssl3_read_bytes */ 3323395f70eSjsing static int 3333395f70eSjsing ssl3_get_record(SSL *s) 3343395f70eSjsing { 33502876cc3Sjsing SSL3_BUFFER_INTERNAL *rb = &(s->s3->rbuf); 33602876cc3Sjsing SSL3_RECORD_INTERNAL *rr = &(s->s3->rrec); 33740038cb8Sjsing uint8_t alert_desc; 33840038cb8Sjsing int al, n; 33940038cb8Sjsing int ret = -1; 3403395f70eSjsing 3413395f70eSjsing again: 3423395f70eSjsing /* check if we have the header */ 3436f7f653bSjsing if ((s->rstate != SSL_ST_READ_BODY) || 3446f7f653bSjsing (s->packet_length < SSL3_RT_HEADER_LENGTH)) { 3453395f70eSjsing CBS header; 3463395f70eSjsing uint16_t len, ssl_version; 3473395f70eSjsing uint8_t type; 3483395f70eSjsing 3493395f70eSjsing n = ssl3_packet_read(s, SSL3_RT_HEADER_LENGTH); 3503395f70eSjsing if (n <= 0) 3513395f70eSjsing return (n); 3523395f70eSjsing 3536f7f653bSjsing s->mac_packet = 1; 3546f7f653bSjsing s->rstate = SSL_ST_READ_BODY; 3553395f70eSjsing 3566f7f653bSjsing if (s->server && s->first_packet) { 3573395f70eSjsing if ((ret = ssl_server_legacy_first_packet(s)) != 1) 3583395f70eSjsing return (ret); 3593395f70eSjsing ret = -1; 3603395f70eSjsing } 3613395f70eSjsing 3626f7f653bSjsing CBS_init(&header, s->packet, SSL3_RT_HEADER_LENGTH); 3633395f70eSjsing 3646182911eSjsing /* Pull apart the header into the SSL3_RECORD_INTERNAL */ 3653395f70eSjsing if (!CBS_get_u8(&header, &type) || 3663395f70eSjsing !CBS_get_u16(&header, &ssl_version) || 3673395f70eSjsing !CBS_get_u16(&header, &len)) { 368c9d7abb7Sbeck SSLerror(s, SSL_R_BAD_PACKET_LENGTH); 3693395f70eSjsing goto err; 3703395f70eSjsing } 3713395f70eSjsing 3723395f70eSjsing rr->type = type; 3733395f70eSjsing rr->length = len; 3743395f70eSjsing 3753395f70eSjsing /* Lets check version */ 3766f7f653bSjsing if (!s->first_packet && ssl_version != s->version) { 3773395f70eSjsing if ((s->version & 0xFF00) == (ssl_version & 0xFF00) && 3786f7f653bSjsing !tls12_record_layer_write_protected(s->rl)) { 3793395f70eSjsing /* Send back error using their minor version number :-) */ 3803395f70eSjsing s->version = ssl_version; 3811365e68cSjsing } 3821365e68cSjsing SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); 3833395f70eSjsing al = SSL_AD_PROTOCOL_VERSION; 384ba06b73eStb goto fatal_err; 3853395f70eSjsing } 3863395f70eSjsing 3873395f70eSjsing if ((ssl_version >> 8) != SSL3_VERSION_MAJOR) { 388c9d7abb7Sbeck SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); 3893395f70eSjsing goto err; 3903395f70eSjsing } 3913395f70eSjsing 39240038cb8Sjsing if (rr->length > rb->len - SSL3_RT_HEADER_LENGTH) { 3933395f70eSjsing al = SSL_AD_RECORD_OVERFLOW; 394c9d7abb7Sbeck SSLerror(s, SSL_R_PACKET_LENGTH_TOO_LONG); 395ba06b73eStb goto fatal_err; 3963395f70eSjsing } 3973395f70eSjsing } 3983395f70eSjsing 3993395f70eSjsing n = ssl3_packet_extend(s, SSL3_RT_HEADER_LENGTH + rr->length); 4003395f70eSjsing if (n <= 0) 4013395f70eSjsing return (n); 4023395f70eSjsing if (n != SSL3_RT_HEADER_LENGTH + rr->length) 4033395f70eSjsing return (n); 4043395f70eSjsing 4056f7f653bSjsing s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ 4063395f70eSjsing 40740038cb8Sjsing /* 40840038cb8Sjsing * A full record has now been read from the wire, which now needs 40940038cb8Sjsing * to be processed. 4103395f70eSjsing */ 4116f7f653bSjsing tls12_record_layer_set_version(s->rl, s->version); 4123395f70eSjsing 413ee4250f6Sjsing if (!tls12_record_layer_open_record(s->rl, s->packet, s->packet_length, 414ee4250f6Sjsing s->s3->rcontent)) { 4156f7f653bSjsing tls12_record_layer_alert(s->rl, &alert_desc); 4163395f70eSjsing 41740038cb8Sjsing if (alert_desc == 0) 41840038cb8Sjsing goto err; 4193395f70eSjsing 42040038cb8Sjsing if (alert_desc == SSL_AD_RECORD_OVERFLOW) 421c9d7abb7Sbeck SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); 42240038cb8Sjsing else if (alert_desc == SSL_AD_BAD_RECORD_MAC) 423c9d7abb7Sbeck SSLerror(s, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); 42440038cb8Sjsing 42540038cb8Sjsing al = alert_desc; 426ba06b73eStb goto fatal_err; 4273395f70eSjsing } 4283395f70eSjsing 4293395f70eSjsing /* we have pulled in a full packet so zero things */ 4306f7f653bSjsing s->packet_length = 0; 4313395f70eSjsing 432ee4250f6Sjsing if (tls_content_remaining(s->s3->rcontent) == 0) { 433b6a22251Sbeck /* 43451bf8b95Sjsing * Zero-length fragments are only permitted for application 43551bf8b95Sjsing * data, as per RFC 5246 section 6.2.1. 43651bf8b95Sjsing */ 43751bf8b95Sjsing if (rr->type != SSL3_RT_APPLICATION_DATA) { 43851bf8b95Sjsing SSLerror(s, SSL_R_BAD_LENGTH); 43951bf8b95Sjsing al = SSL_AD_UNEXPECTED_MESSAGE; 44051bf8b95Sjsing goto fatal_err; 44151bf8b95Sjsing } 44251bf8b95Sjsing 443ee4250f6Sjsing tls_content_clear(s->s3->rcontent); 444ee4250f6Sjsing 44551bf8b95Sjsing /* 44640038cb8Sjsing * CBC countermeasures for known IV weaknesses can legitimately 44740038cb8Sjsing * insert a single empty record, so we allow ourselves to read 44840038cb8Sjsing * once past a single empty record without forcing want_read. 449b6a22251Sbeck */ 4506f7f653bSjsing if (s->empty_record_count++ > SSL_MAX_EMPTY_RECORDS) { 451c9d7abb7Sbeck SSLerror(s, SSL_R_PEER_BEHAVING_BADLY); 452b6a22251Sbeck return -1; 453b6a22251Sbeck } 4546f7f653bSjsing if (s->empty_record_count > 1) { 455b6a22251Sbeck ssl_force_want_read(s); 456b6a22251Sbeck return -1; 457b6a22251Sbeck } 4583395f70eSjsing goto again; 459b6a22251Sbeck } 4603395f70eSjsing 4616f7f653bSjsing s->empty_record_count = 0; 46240038cb8Sjsing 4633395f70eSjsing return (1); 4643395f70eSjsing 465ba06b73eStb fatal_err: 4663395f70eSjsing ssl3_send_alert(s, SSL3_AL_FATAL, al); 4673395f70eSjsing err: 4683395f70eSjsing return (ret); 4693395f70eSjsing } 4703395f70eSjsing 4713395f70eSjsing /* Call this to write data in records of type 'type' 4723395f70eSjsing * It will return <= 0 if not all data has been sent or non-blocking IO. 4733395f70eSjsing */ 4743395f70eSjsing int 4753395f70eSjsing ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) 4763395f70eSjsing { 4773395f70eSjsing const unsigned char *buf = buf_; 4783395f70eSjsing unsigned int tot, n, nw; 4793395f70eSjsing int i; 4803395f70eSjsing 4813395f70eSjsing if (len < 0) { 482c9d7abb7Sbeck SSLerror(s, ERR_R_INTERNAL_ERROR); 4833395f70eSjsing return -1; 4843395f70eSjsing } 4853395f70eSjsing 4866f7f653bSjsing s->rwstate = SSL_NOTHING; 48702876cc3Sjsing tot = s->s3->wnum; 48802876cc3Sjsing s->s3->wnum = 0; 4893395f70eSjsing 4906f7f653bSjsing if (SSL_in_init(s) && !s->in_handshake) { 4916f7f653bSjsing i = s->handshake_func(s); 4923395f70eSjsing if (i < 0) 4933395f70eSjsing return (i); 4943395f70eSjsing if (i == 0) { 495c9d7abb7Sbeck SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); 4963395f70eSjsing return -1; 4973395f70eSjsing } 4983395f70eSjsing } 4993395f70eSjsing 5003395f70eSjsing if (len < tot) 5013395f70eSjsing len = tot; 5023395f70eSjsing n = (len - tot); 5033395f70eSjsing for (;;) { 5043395f70eSjsing if (n > s->max_send_fragment) 5053395f70eSjsing nw = s->max_send_fragment; 5063395f70eSjsing else 5073395f70eSjsing nw = n; 5083395f70eSjsing 509f91e30d7Sjsing i = do_ssl3_write(s, type, &(buf[tot]), nw); 5103395f70eSjsing if (i <= 0) { 51102876cc3Sjsing s->s3->wnum = tot; 5123395f70eSjsing return i; 5133395f70eSjsing } 5143395f70eSjsing 5153395f70eSjsing if ((i == (int)n) || (type == SSL3_RT_APPLICATION_DATA && 5166f7f653bSjsing (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { 5173395f70eSjsing /* 5183395f70eSjsing * Next chunk of data should get another prepended 5193395f70eSjsing * empty fragment in ciphersuites with known-IV 5203395f70eSjsing * weakness. 5213395f70eSjsing */ 52202876cc3Sjsing s->s3->empty_fragment_done = 0; 5233395f70eSjsing 5243395f70eSjsing return tot + i; 5253395f70eSjsing } 5263395f70eSjsing 5273395f70eSjsing n -= i; 5283395f70eSjsing tot += i; 5293395f70eSjsing } 5303395f70eSjsing } 5313395f70eSjsing 5323395f70eSjsing static int 533f91e30d7Sjsing do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) 534f91e30d7Sjsing { 53502876cc3Sjsing SSL3_BUFFER_INTERNAL *wb = &(s->s3->wbuf); 536f91e30d7Sjsing SSL_SESSION *sess = s->session; 53718691bb1Sjsing int need_empty_fragment = 0; 538d6d3cb6fSjsing size_t align, out_len; 539d6d3cb6fSjsing CBB cbb; 54018691bb1Sjsing int ret; 541f91e30d7Sjsing 542d6d3cb6fSjsing memset(&cbb, 0, sizeof(cbb)); 543d6d3cb6fSjsing 544f91e30d7Sjsing if (wb->buf == NULL) 545f91e30d7Sjsing if (!ssl3_setup_write_buffer(s)) 546f91e30d7Sjsing return -1; 547f91e30d7Sjsing 54818691bb1Sjsing /* 54918691bb1Sjsing * First check if there is a SSL3_BUFFER_INTERNAL still being written 55018691bb1Sjsing * out. This will happen with non blocking IO. 55118691bb1Sjsing */ 552f91e30d7Sjsing if (wb->left != 0) 553f91e30d7Sjsing return (ssl3_write_pending(s, type, buf, len)); 554f91e30d7Sjsing 55518691bb1Sjsing /* If we have an alert to send, let's send it. */ 55602876cc3Sjsing if (s->s3->alert_dispatch) { 557e3dbb073Sjsing if ((ret = ssl3_dispatch_alert(s)) <= 0) 55818691bb1Sjsing return (ret); 55918691bb1Sjsing /* If it went, fall through and send more stuff. */ 56018691bb1Sjsing 56118691bb1Sjsing /* We may have released our buffer, if so get it again. */ 562f91e30d7Sjsing if (wb->buf == NULL) 563f91e30d7Sjsing if (!ssl3_setup_write_buffer(s)) 564f91e30d7Sjsing return -1; 565f91e30d7Sjsing } 566f91e30d7Sjsing 567f91e30d7Sjsing if (len == 0) 568f91e30d7Sjsing return 0; 569f91e30d7Sjsing 570f91e30d7Sjsing /* 571f91e30d7Sjsing * Countermeasure against known-IV weakness in CBC ciphersuites 57218691bb1Sjsing * (see http://www.openssl.org/~bodo/tls-cbc.txt). Note that this 57318691bb1Sjsing * is unnecessary for AEAD. 574f91e30d7Sjsing */ 5756f7f653bSjsing if (sess != NULL && tls12_record_layer_write_protected(s->rl)) { 57602876cc3Sjsing if (s->s3->need_empty_fragments && 57702876cc3Sjsing !s->s3->empty_fragment_done && 57818691bb1Sjsing type == SSL3_RT_APPLICATION_DATA) 57918691bb1Sjsing need_empty_fragment = 1; 58018691bb1Sjsing } 58118691bb1Sjsing 58218691bb1Sjsing /* 58318691bb1Sjsing * An extra fragment would be a couple of cipher blocks, which would 58418691bb1Sjsing * be a multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real 58518691bb1Sjsing * payload, then we can just simply pretend we have two headers. 58618691bb1Sjsing */ 58718691bb1Sjsing align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH; 58818691bb1Sjsing if (need_empty_fragment) 58918691bb1Sjsing align += SSL3_RT_HEADER_LENGTH; 590f91e30d7Sjsing align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); 591f91e30d7Sjsing wb->offset = align; 592f91e30d7Sjsing 593d6d3cb6fSjsing if (!CBB_init_fixed(&cbb, wb->buf + align, wb->len - align)) 594d6d3cb6fSjsing goto err; 595d6d3cb6fSjsing 59656e1ead7Stb tls12_record_layer_set_version(s->rl, s->version); 597acef91a0Sjsing 59818691bb1Sjsing if (need_empty_fragment) { 5996f7f653bSjsing if (!tls12_record_layer_seal_record(s->rl, type, 600acef91a0Sjsing buf, 0, &cbb)) 601f91e30d7Sjsing goto err; 60202876cc3Sjsing s->s3->empty_fragment_done = 1; 603f91e30d7Sjsing } 604f91e30d7Sjsing 6056f7f653bSjsing if (!tls12_record_layer_seal_record(s->rl, type, buf, len, &cbb)) 606f91e30d7Sjsing goto err; 607f91e30d7Sjsing 608d6d3cb6fSjsing if (!CBB_finish(&cbb, NULL, &out_len)) 609d6d3cb6fSjsing goto err; 610d6d3cb6fSjsing 611d6d3cb6fSjsing wb->left = out_len; 6123395f70eSjsing 61318691bb1Sjsing /* 61418691bb1Sjsing * Memorize arguments so that ssl3_write_pending can detect 61518691bb1Sjsing * bad write retries later. 61618691bb1Sjsing */ 61702876cc3Sjsing s->s3->wpend_tot = len; 61802876cc3Sjsing s->s3->wpend_buf = buf; 61902876cc3Sjsing s->s3->wpend_type = type; 62002876cc3Sjsing s->s3->wpend_ret = len; 6213395f70eSjsing 62218691bb1Sjsing /* We now just need to write the buffer. */ 6233395f70eSjsing return ssl3_write_pending(s, type, buf, len); 62418691bb1Sjsing 6253395f70eSjsing err: 626d6d3cb6fSjsing CBB_cleanup(&cbb); 627d6d3cb6fSjsing 6283395f70eSjsing return -1; 6293395f70eSjsing } 6303395f70eSjsing 63102876cc3Sjsing /* if s->s3->wbuf.left != 0, we need to call this */ 6323395f70eSjsing int 6333395f70eSjsing ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len) 6343395f70eSjsing { 6353395f70eSjsing int i; 63602876cc3Sjsing SSL3_BUFFER_INTERNAL *wb = &(s->s3->wbuf); 6373395f70eSjsing 6383395f70eSjsing /* XXXX */ 63902876cc3Sjsing if ((s->s3->wpend_tot > (int)len) || ((s->s3->wpend_buf != buf) && 6406f7f653bSjsing !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) || 64102876cc3Sjsing (s->s3->wpend_type != type)) { 642c9d7abb7Sbeck SSLerror(s, SSL_R_BAD_WRITE_RETRY); 6433395f70eSjsing return (-1); 6443395f70eSjsing } 6453395f70eSjsing 6463395f70eSjsing for (;;) { 6473395f70eSjsing errno = 0; 6483395f70eSjsing if (s->wbio != NULL) { 6496f7f653bSjsing s->rwstate = SSL_WRITING; 650821d9f84Sjsing i = BIO_write(s->wbio, (char *)&(wb->buf[wb->offset]), 6513395f70eSjsing (unsigned int)wb->left); 6523395f70eSjsing } else { 653c9d7abb7Sbeck SSLerror(s, SSL_R_BIO_NOT_SET); 6543395f70eSjsing i = -1; 6553395f70eSjsing } 6563395f70eSjsing if (i == wb->left) { 6573395f70eSjsing wb->left = 0; 6583395f70eSjsing wb->offset += i; 6596f7f653bSjsing if (s->mode & SSL_MODE_RELEASE_BUFFERS && 6609e659261Sjsing !SSL_is_dtls(s)) 6613395f70eSjsing ssl3_release_write_buffer(s); 6626f7f653bSjsing s->rwstate = SSL_NOTHING; 66302876cc3Sjsing return (s->s3->wpend_ret); 6643395f70eSjsing } else if (i <= 0) { 6653395f70eSjsing /* 6663395f70eSjsing * For DTLS, just drop it. That's kind of the 6673395f70eSjsing * whole point in using a datagram service. 6683395f70eSjsing */ 6699e659261Sjsing if (SSL_is_dtls(s)) 6703395f70eSjsing wb->left = 0; 6713395f70eSjsing return (i); 6723395f70eSjsing } 6733395f70eSjsing wb->offset += i; 6743395f70eSjsing wb->left -= i; 6753395f70eSjsing } 6763395f70eSjsing } 6773395f70eSjsing 678b1a5c5c8Sjsing static ssize_t 679b1a5c5c8Sjsing ssl3_read_cb(void *buf, size_t n, void *cb_arg) 680b1a5c5c8Sjsing { 681b1a5c5c8Sjsing SSL *s = cb_arg; 682b1a5c5c8Sjsing 683ee4250f6Sjsing return tls_content_read(s->s3->rcontent, buf, n); 684b1a5c5c8Sjsing } 685b1a5c5c8Sjsing 686b1a5c5c8Sjsing #define SSL3_ALERT_LENGTH 2 687b1a5c5c8Sjsing 68856fd52a7Sjsing int 68956fd52a7Sjsing ssl3_read_alert(SSL *s) 69056fd52a7Sjsing { 69156fd52a7Sjsing uint8_t alert_level, alert_descr; 692b1a5c5c8Sjsing ssize_t ret; 6937ec9e62fSjsing CBS cbs; 69456fd52a7Sjsing 69556fd52a7Sjsing /* 69656fd52a7Sjsing * TLSv1.2 permits an alert to be fragmented across multiple records or 69756fd52a7Sjsing * for multiple alerts to be be coalesced into a single alert record. 69856fd52a7Sjsing * In the case of DTLS, there is no way to reassemble an alert 69956fd52a7Sjsing * fragmented across multiple records, hence a full alert must be 70056fd52a7Sjsing * available in the record. 70156fd52a7Sjsing */ 702b1a5c5c8Sjsing if (s->s3->alert_fragment == NULL) { 703b1a5c5c8Sjsing if ((s->s3->alert_fragment = tls_buffer_new(0)) == NULL) 704b1a5c5c8Sjsing return -1; 705b1a5c5c8Sjsing tls_buffer_set_capacity_limit(s->s3->alert_fragment, 706b1a5c5c8Sjsing SSL3_ALERT_LENGTH); 70756fd52a7Sjsing } 708b1a5c5c8Sjsing ret = tls_buffer_extend(s->s3->alert_fragment, SSL3_ALERT_LENGTH, 709b1a5c5c8Sjsing ssl3_read_cb, s); 710b1a5c5c8Sjsing if (ret <= 0 && ret != TLS_IO_WANT_POLLIN) 711b1a5c5c8Sjsing return -1; 712b1a5c5c8Sjsing if (ret != SSL3_ALERT_LENGTH) { 71356fd52a7Sjsing if (SSL_is_dtls(s)) { 71456fd52a7Sjsing SSLerror(s, SSL_R_BAD_LENGTH); 71556fd52a7Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); 71656fd52a7Sjsing return -1; 71756fd52a7Sjsing } 71856fd52a7Sjsing return 1; 71956fd52a7Sjsing } 72056fd52a7Sjsing 721b1a5c5c8Sjsing if (!tls_buffer_data(s->s3->alert_fragment, &cbs)) 722b1a5c5c8Sjsing return -1; 72356fd52a7Sjsing 7247ec9e62fSjsing ssl_msg_callback_cbs(s, 0, SSL3_RT_ALERT, &cbs); 7257ec9e62fSjsing 7267ec9e62fSjsing if (!CBS_get_u8(&cbs, &alert_level)) 7277ec9e62fSjsing return -1; 7287ec9e62fSjsing if (!CBS_get_u8(&cbs, &alert_descr)) 7297ec9e62fSjsing return -1; 7307ec9e62fSjsing 731b1a5c5c8Sjsing tls_buffer_free(s->s3->alert_fragment); 732b1a5c5c8Sjsing s->s3->alert_fragment = NULL; 73356fd52a7Sjsing 73456fd52a7Sjsing ssl_info_callback(s, SSL_CB_READ_ALERT, 73556fd52a7Sjsing (alert_level << 8) | alert_descr); 73656fd52a7Sjsing 73756fd52a7Sjsing if (alert_level == SSL3_AL_WARNING) { 73856fd52a7Sjsing s->s3->warn_alert = alert_descr; 73956fd52a7Sjsing if (alert_descr == SSL_AD_CLOSE_NOTIFY) { 7406f7f653bSjsing s->shutdown |= SSL_RECEIVED_SHUTDOWN; 74156fd52a7Sjsing return 0; 74256fd52a7Sjsing } 74356fd52a7Sjsing /* We requested renegotiation and the peer rejected it. */ 74456fd52a7Sjsing if (alert_descr == SSL_AD_NO_RENEGOTIATION) { 74556fd52a7Sjsing SSLerror(s, SSL_R_NO_RENEGOTIATION); 74656fd52a7Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, 74756fd52a7Sjsing SSL_AD_HANDSHAKE_FAILURE); 74856fd52a7Sjsing return -1; 74956fd52a7Sjsing } 75056fd52a7Sjsing } else if (alert_level == SSL3_AL_FATAL) { 7516f7f653bSjsing s->rwstate = SSL_NOTHING; 75256fd52a7Sjsing s->s3->fatal_alert = alert_descr; 75356fd52a7Sjsing SSLerror(s, SSL_AD_REASON_OFFSET + alert_descr); 75456fd52a7Sjsing ERR_asprintf_error_data("SSL alert number %d", alert_descr); 7556f7f653bSjsing s->shutdown |= SSL_RECEIVED_SHUTDOWN; 75656fd52a7Sjsing SSL_CTX_remove_session(s->ctx, s->session); 75756fd52a7Sjsing return 0; 75856fd52a7Sjsing } else { 75956fd52a7Sjsing SSLerror(s, SSL_R_UNKNOWN_ALERT_TYPE); 76056fd52a7Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); 76156fd52a7Sjsing return -1; 76256fd52a7Sjsing } 76356fd52a7Sjsing 76456fd52a7Sjsing return 1; 76556fd52a7Sjsing } 76656fd52a7Sjsing 767b23067a6Sjsing int 768b23067a6Sjsing ssl3_read_change_cipher_spec(SSL *s) 769b23067a6Sjsing { 770ee4250f6Sjsing const uint8_t ccs[1] = { SSL3_MT_CCS }; 771b23067a6Sjsing 772b23067a6Sjsing /* 773b23067a6Sjsing * 'Change Cipher Spec' is just a single byte, so we know exactly what 774b23067a6Sjsing * the record payload has to look like. 775b23067a6Sjsing */ 776ee4250f6Sjsing if (tls_content_remaining(s->s3->rcontent) != sizeof(ccs)) { 777b23067a6Sjsing SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC); 778b23067a6Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); 779b23067a6Sjsing return -1; 780b23067a6Sjsing } 781ee4250f6Sjsing if (!tls_content_equal(s->s3->rcontent, ccs, sizeof(ccs))) { 782b23067a6Sjsing SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC); 783b23067a6Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); 784b23067a6Sjsing return -1; 785b23067a6Sjsing } 786b23067a6Sjsing 787b23067a6Sjsing /* XDTLS: check that epoch is consistent */ 788b23067a6Sjsing 789ee4250f6Sjsing ssl_msg_callback_cbs(s, 0, SSL3_RT_CHANGE_CIPHER_SPEC, 790ee4250f6Sjsing tls_content_cbs(s->s3->rcontent)); 791b23067a6Sjsing 792b23067a6Sjsing /* Check that we have a cipher to change to. */ 793b23067a6Sjsing if (s->s3->hs.cipher == NULL) { 794b23067a6Sjsing SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); 795b23067a6Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); 796b23067a6Sjsing return -1; 797b23067a6Sjsing } 798b23067a6Sjsing 799b23067a6Sjsing /* Check that we should be receiving a Change Cipher Spec. */ 800b23067a6Sjsing if (SSL_is_dtls(s)) { 801b23067a6Sjsing if (!s->d1->change_cipher_spec_ok) { 802b23067a6Sjsing /* 803b23067a6Sjsing * We can't process a CCS now, because previous 804b23067a6Sjsing * handshake messages are still missing, so just 805b23067a6Sjsing * drop it. 806b23067a6Sjsing */ 807ee4250f6Sjsing tls_content_clear(s->s3->rcontent); 808b23067a6Sjsing return 1; 809b23067a6Sjsing } 810b23067a6Sjsing s->d1->change_cipher_spec_ok = 0; 811b23067a6Sjsing } else { 812b23067a6Sjsing if ((s->s3->flags & SSL3_FLAGS_CCS_OK) == 0) { 813b23067a6Sjsing SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); 814b23067a6Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, 815b23067a6Sjsing SSL_AD_UNEXPECTED_MESSAGE); 816b23067a6Sjsing return -1; 817b23067a6Sjsing } 818b23067a6Sjsing s->s3->flags &= ~SSL3_FLAGS_CCS_OK; 819b23067a6Sjsing } 820b23067a6Sjsing 821ee4250f6Sjsing tls_content_clear(s->s3->rcontent); 822b23067a6Sjsing 823b23067a6Sjsing s->s3->change_cipher_spec = 1; 824b23067a6Sjsing if (!ssl3_do_change_cipher_spec(s)) 825b23067a6Sjsing return -1; 826b23067a6Sjsing 827b23067a6Sjsing return 1; 828b23067a6Sjsing } 829b23067a6Sjsing 830225d6b92Sjsing static int 831225d6b92Sjsing ssl3_read_handshake_unexpected(SSL *s) 832225d6b92Sjsing { 833d7e52203Sjsing uint32_t hs_msg_length; 834d7e52203Sjsing uint8_t hs_msg_type; 835b1a5c5c8Sjsing ssize_t ssret; 836d7e52203Sjsing CBS cbs; 837d7e52203Sjsing int ret; 838225d6b92Sjsing 839225d6b92Sjsing /* 840225d6b92Sjsing * We need four bytes of handshake data so we have a handshake message 841225d6b92Sjsing * header - this may be in the same record or fragmented across multiple 842225d6b92Sjsing * records. 843225d6b92Sjsing */ 844b1a5c5c8Sjsing if (s->s3->handshake_fragment == NULL) { 845b1a5c5c8Sjsing if ((s->s3->handshake_fragment = tls_buffer_new(0)) == NULL) 846b1a5c5c8Sjsing return -1; 847b1a5c5c8Sjsing tls_buffer_set_capacity_limit(s->s3->handshake_fragment, 848b1a5c5c8Sjsing SSL3_HM_HEADER_LENGTH); 849225d6b92Sjsing } 850b1a5c5c8Sjsing ssret = tls_buffer_extend(s->s3->handshake_fragment, SSL3_HM_HEADER_LENGTH, 851b1a5c5c8Sjsing ssl3_read_cb, s); 852b1a5c5c8Sjsing if (ssret <= 0 && ssret != TLS_IO_WANT_POLLIN) 853b1a5c5c8Sjsing return -1; 854b1a5c5c8Sjsing if (ssret != SSL3_HM_HEADER_LENGTH) 855225d6b92Sjsing return 1; 856225d6b92Sjsing 8576f7f653bSjsing if (s->in_handshake) { 858225d6b92Sjsing SSLerror(s, ERR_R_INTERNAL_ERROR); 859225d6b92Sjsing return -1; 860225d6b92Sjsing } 861225d6b92Sjsing 862225d6b92Sjsing /* 863225d6b92Sjsing * This code currently deals with HelloRequest and ClientHello messages - 864225d6b92Sjsing * anything else is pushed to the handshake_func. Almost all of this 865225d6b92Sjsing * belongs in the client/server handshake code. 866225d6b92Sjsing */ 867225d6b92Sjsing 868d7e52203Sjsing /* Parse handshake message header. */ 869b1a5c5c8Sjsing if (!tls_buffer_data(s->s3->handshake_fragment, &cbs)) 870b1a5c5c8Sjsing return -1; 871d7e52203Sjsing if (!CBS_get_u8(&cbs, &hs_msg_type)) 872d7e52203Sjsing return -1; 873d7e52203Sjsing if (!CBS_get_u24(&cbs, &hs_msg_length)) 874d7e52203Sjsing return -1; 875225d6b92Sjsing 876d7e52203Sjsing if (hs_msg_type == SSL3_MT_HELLO_REQUEST) { 877d7e52203Sjsing /* 878d7e52203Sjsing * Incoming HelloRequest messages should only be received by a 879d7e52203Sjsing * client. A server may send these at any time - a client should 880d7e52203Sjsing * ignore the message if received in the middle of a handshake. 881d7e52203Sjsing * See RFC 5246 sections 7.4 and 7.4.1.1. 882d7e52203Sjsing */ 883d7e52203Sjsing if (s->server) { 884d7e52203Sjsing SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); 885d7e52203Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, 886d7e52203Sjsing SSL_AD_UNEXPECTED_MESSAGE); 887d7e52203Sjsing return -1; 888d7e52203Sjsing } 889d7e52203Sjsing 890d7e52203Sjsing if (hs_msg_length != 0) { 891225d6b92Sjsing SSLerror(s, SSL_R_BAD_HELLO_REQUEST); 892225d6b92Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); 893225d6b92Sjsing return -1; 894225d6b92Sjsing } 895225d6b92Sjsing 896b1a5c5c8Sjsing if (!tls_buffer_data(s->s3->handshake_fragment, &cbs)) 897b1a5c5c8Sjsing return -1; 898b1a5c5c8Sjsing ssl_msg_callback_cbs(s, 0, SSL3_RT_HANDSHAKE, &cbs); 899225d6b92Sjsing 900b1a5c5c8Sjsing tls_buffer_free(s->s3->handshake_fragment); 901b1a5c5c8Sjsing s->s3->handshake_fragment = NULL; 902225d6b92Sjsing 903d7e52203Sjsing /* 904d7e52203Sjsing * It should be impossible to hit this, but keep the safety 905d7e52203Sjsing * harness for now... 906d7e52203Sjsing */ 907387303bbSjsing if (s->session == NULL || s->s3->hs.cipher == NULL) 908225d6b92Sjsing return 1; 909225d6b92Sjsing 910d7e52203Sjsing /* 911d7e52203Sjsing * Ignore this message if we're currently handshaking, 912d7e52203Sjsing * renegotiation is already pending or renegotiation is disabled 913d7e52203Sjsing * via flags. 914d7e52203Sjsing */ 915d7e52203Sjsing if (!SSL_is_init_finished(s) || s->s3->renegotiate || 916d7e52203Sjsing (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) 917d7e52203Sjsing return 1; 918d7e52203Sjsing 919d7e52203Sjsing if (!ssl3_renegotiate(s)) 920d7e52203Sjsing return 1; 921d7e52203Sjsing if (!ssl3_renegotiate_check(s)) 922d7e52203Sjsing return 1; 923d7e52203Sjsing 924d7e52203Sjsing } else if (hs_msg_type == SSL3_MT_CLIENT_HELLO) { 925d7e52203Sjsing /* 926d7e52203Sjsing * Incoming ClientHello messages should only be received by a 927d7e52203Sjsing * server. A client may send these in response to server 928d7e52203Sjsing * initiated renegotiation (HelloRequest) or in order to 929d7e52203Sjsing * initiate renegotiation by the client. See RFC 5246 section 930d7e52203Sjsing * 7.4.1.2. 931d7e52203Sjsing */ 932d7e52203Sjsing if (!s->server) { 933d7e52203Sjsing SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); 934d7e52203Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, 935d7e52203Sjsing SSL_AD_UNEXPECTED_MESSAGE); 936225d6b92Sjsing return -1; 937225d6b92Sjsing } 938225d6b92Sjsing 939d7e52203Sjsing /* 940d7e52203Sjsing * A client should not be sending a ClientHello unless we're not 941d7e52203Sjsing * currently handshaking. 942225d6b92Sjsing */ 943d7e52203Sjsing if (!SSL_is_init_finished(s)) { 944d7e52203Sjsing SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); 945d7e52203Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, 946d7e52203Sjsing SSL_AD_UNEXPECTED_MESSAGE); 947d7e52203Sjsing return -1; 948d7e52203Sjsing } 949d7e52203Sjsing 9506f7f653bSjsing if ((s->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0) { 951d7e52203Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, 952d7e52203Sjsing SSL_AD_NO_RENEGOTIATION); 953d7e52203Sjsing return -1; 954d7e52203Sjsing } 955d7e52203Sjsing 956387303bbSjsing if (s->session == NULL || s->s3->hs.cipher == NULL) { 957d7e52203Sjsing SSLerror(s, ERR_R_INTERNAL_ERROR); 958d7e52203Sjsing return -1; 959d7e52203Sjsing } 960d7e52203Sjsing 961d7e52203Sjsing /* Client requested renegotiation but it is not permitted. */ 962d7e52203Sjsing if (!s->s3->send_connection_binding || 963d7e52203Sjsing (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) { 964d7e52203Sjsing ssl3_send_alert(s, SSL3_AL_WARNING, 965d7e52203Sjsing SSL_AD_NO_RENEGOTIATION); 966225d6b92Sjsing return 1; 967225d6b92Sjsing } 968225d6b92Sjsing 969d7e52203Sjsing s->s3->hs.state = SSL_ST_ACCEPT; 9706f7f653bSjsing s->renegotiate = 1; 9716f7f653bSjsing s->new_session = 1; 972d7e52203Sjsing 973d7e52203Sjsing } else { 974d7e52203Sjsing SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); 975d7e52203Sjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); 976d7e52203Sjsing return -1; 977225d6b92Sjsing } 978d7e52203Sjsing 9796f7f653bSjsing if ((ret = s->handshake_func(s)) < 0) 980d7e52203Sjsing return ret; 981d7e52203Sjsing if (ret == 0) { 982225d6b92Sjsing SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); 983d7e52203Sjsing return -1; 984225d6b92Sjsing } 985225d6b92Sjsing 9866f7f653bSjsing if (!(s->mode & SSL_MODE_AUTO_RETRY)) { 987225d6b92Sjsing if (s->s3->rbuf.left == 0) { 988225d6b92Sjsing ssl_force_want_read(s); 989d7e52203Sjsing return -1; 990225d6b92Sjsing } 991225d6b92Sjsing } 992225d6b92Sjsing 993d7e52203Sjsing /* 994d7e52203Sjsing * We either finished a handshake or ignored the request, now try again 995d7e52203Sjsing * to obtain the (application) data we were asked for. 996d7e52203Sjsing */ 997225d6b92Sjsing return 1; 998225d6b92Sjsing } 999225d6b92Sjsing 10003395f70eSjsing /* Return up to 'len' payload bytes received in 'type' records. 10013395f70eSjsing * 'type' is one of the following: 10023395f70eSjsing * 10033395f70eSjsing * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) 10043395f70eSjsing * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) 10053395f70eSjsing * - 0 (during a shutdown, no data has to be returned) 10063395f70eSjsing * 10073395f70eSjsing * If we don't have stored data to work from, read a SSL/TLS record first 10083395f70eSjsing * (possibly multiple records if we still don't have anything to return). 10093395f70eSjsing * 10103395f70eSjsing * This function must handle any surprises the peer may have for us, such as 10113395f70eSjsing * Alert records (e.g. close_notify), ChangeCipherSpec records (not really 10123395f70eSjsing * a surprise, but handled as if it were), or renegotiation requests. 10133395f70eSjsing * Also if record payloads contain fragments too small to process, we store 10143395f70eSjsing * them until there is enough for the respective protocol (the record protocol 10153395f70eSjsing * may use arbitrary fragmentation and even interleaving): 10163395f70eSjsing * Change cipher spec protocol 10173395f70eSjsing * just 1 byte needed, no need for keeping anything stored 10183395f70eSjsing * Alert protocol 10193395f70eSjsing * 2 bytes needed (AlertLevel, AlertDescription) 10203395f70eSjsing * Handshake protocol 10213395f70eSjsing * 4 bytes needed (HandshakeType, uint24 length) -- we just have 10223395f70eSjsing * to detect unexpected Client Hello and Hello Request messages 10233395f70eSjsing * here, anything else is handled by higher layers 10243395f70eSjsing * Application data protocol 10253395f70eSjsing * none of our business 10263395f70eSjsing */ 10273395f70eSjsing int 10283395f70eSjsing ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) 10293395f70eSjsing { 1030c2712b29Sjsing int rrcount = 0; 1031ee4250f6Sjsing ssize_t ssret; 1032824388bbSjsing int ret; 10333395f70eSjsing 1034824388bbSjsing if (s->s3->rbuf.buf == NULL) { 10353395f70eSjsing if (!ssl3_setup_read_buffer(s)) 1036824388bbSjsing return -1; 1037824388bbSjsing } 10383395f70eSjsing 1039ee4250f6Sjsing if (s->s3->rcontent == NULL) { 1040ee4250f6Sjsing if ((s->s3->rcontent = tls_content_new()) == NULL) 1041ee4250f6Sjsing return -1; 1042ee4250f6Sjsing } 1043ee4250f6Sjsing 10443395f70eSjsing if (len < 0) { 1045c9d7abb7Sbeck SSLerror(s, ERR_R_INTERNAL_ERROR); 10463395f70eSjsing return -1; 10473395f70eSjsing } 10483395f70eSjsing 1049824388bbSjsing if (type != 0 && type != SSL3_RT_APPLICATION_DATA && 1050824388bbSjsing type != SSL3_RT_HANDSHAKE) { 1051824388bbSjsing SSLerror(s, ERR_R_INTERNAL_ERROR); 1052824388bbSjsing return -1; 1053824388bbSjsing } 1054824388bbSjsing if (peek && type != SSL3_RT_APPLICATION_DATA) { 1055c9d7abb7Sbeck SSLerror(s, ERR_R_INTERNAL_ERROR); 10563395f70eSjsing return -1; 10573395f70eSjsing } 10583395f70eSjsing 1059b1a5c5c8Sjsing if (type == SSL3_RT_HANDSHAKE && 1060b1a5c5c8Sjsing s->s3->handshake_fragment != NULL && 1061b1a5c5c8Sjsing tls_buffer_remaining(s->s3->handshake_fragment) > 0) { 1062b1a5c5c8Sjsing ssize_t ssn; 10633395f70eSjsing 1064b1a5c5c8Sjsing if ((ssn = tls_buffer_read(s->s3->handshake_fragment, buf, 1065b1a5c5c8Sjsing len)) <= 0) 1066b1a5c5c8Sjsing return -1; 1067b1a5c5c8Sjsing 1068b1a5c5c8Sjsing if (tls_buffer_remaining(s->s3->handshake_fragment) == 0) { 1069b1a5c5c8Sjsing tls_buffer_free(s->s3->handshake_fragment); 1070b1a5c5c8Sjsing s->s3->handshake_fragment = NULL; 10713395f70eSjsing } 1072b1a5c5c8Sjsing 1073b1a5c5c8Sjsing return (int)ssn; 10743395f70eSjsing } 10753395f70eSjsing 10766f7f653bSjsing if (SSL_in_init(s) && !s->in_handshake) { 10776f7f653bSjsing if ((ret = s->handshake_func(s)) < 0) 1078824388bbSjsing return ret; 1079824388bbSjsing if (ret == 0) { 1080c9d7abb7Sbeck SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); 1081824388bbSjsing return -1; 10823395f70eSjsing } 10833395f70eSjsing } 10843395f70eSjsing 10853395f70eSjsing start: 10863395f70eSjsing /* 10873395f70eSjsing * Do not process more than three consecutive records, otherwise the 10883395f70eSjsing * peer can cause us to loop indefinitely. Instead, return with an 10893395f70eSjsing * SSL_ERROR_WANT_READ so the caller can choose when to handle further 10903395f70eSjsing * processing. In the future, the total number of non-handshake and 10913395f70eSjsing * non-application data records per connection should probably also be 10923395f70eSjsing * limited... 10933395f70eSjsing */ 10943395f70eSjsing if (rrcount++ >= 3) { 1095a2584b01Sbeck ssl_force_want_read(s); 10963395f70eSjsing return -1; 10973395f70eSjsing } 10983395f70eSjsing 10996f7f653bSjsing s->rwstate = SSL_NOTHING; 11003395f70eSjsing 1101ee4250f6Sjsing if (tls_content_remaining(s->s3->rcontent) == 0) { 1102824388bbSjsing if ((ret = ssl3_get_record(s)) <= 0) 1103824388bbSjsing return ret; 11043395f70eSjsing } 11053395f70eSjsing 1106824388bbSjsing /* We now have a packet which can be read and processed. */ 11073395f70eSjsing 1108ee4250f6Sjsing if (s->s3->change_cipher_spec && 1109ee4250f6Sjsing tls_content_type(s->s3->rcontent) != SSL3_RT_HANDSHAKE) { 1110c9d7abb7Sbeck SSLerror(s, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); 1111824388bbSjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); 1112824388bbSjsing return -1; 11133395f70eSjsing } 11143395f70eSjsing 1115824388bbSjsing /* 1116824388bbSjsing * If the other end has shut down, throw anything we read away (even in 1117824388bbSjsing * 'peek' mode). 1118824388bbSjsing */ 11196f7f653bSjsing if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { 11206f7f653bSjsing s->rwstate = SSL_NOTHING; 1121ee4250f6Sjsing tls_content_clear(s->s3->rcontent); 1122ee4250f6Sjsing s->s3->rrec.length = 0; 1123824388bbSjsing return 0; 11243395f70eSjsing } 11253395f70eSjsing 11263395f70eSjsing /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ 1127ee4250f6Sjsing if (tls_content_type(s->s3->rcontent) == type) { 1128824388bbSjsing /* 1129824388bbSjsing * Make sure that we are not getting application data when we 1130824388bbSjsing * are doing a handshake for the first time. 1131824388bbSjsing */ 11321365e68cSjsing if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA && 11336f7f653bSjsing !tls12_record_layer_read_protected(s->rl)) { 1134c9d7abb7Sbeck SSLerror(s, SSL_R_APP_DATA_IN_HANDSHAKE); 1135824388bbSjsing ssl3_send_alert(s, SSL3_AL_FATAL, 1136824388bbSjsing SSL_AD_UNEXPECTED_MESSAGE); 1137824388bbSjsing return -1; 11383395f70eSjsing } 11393395f70eSjsing 11403395f70eSjsing if (len <= 0) 1141824388bbSjsing return len; 11423395f70eSjsing 1143ee4250f6Sjsing if (peek) { 1144ee4250f6Sjsing ssret = tls_content_peek(s->s3->rcontent, buf, len); 1145ee4250f6Sjsing } else { 1146ee4250f6Sjsing ssret = tls_content_read(s->s3->rcontent, buf, len); 1147ee4250f6Sjsing } 1148ee4250f6Sjsing if (ssret < INT_MIN || ssret > INT_MAX) 1149ee4250f6Sjsing return -1; 1150ee4250f6Sjsing if (ssret < 0) 1151ee4250f6Sjsing return (int)ssret; 11523395f70eSjsing 1153ee4250f6Sjsing if (tls_content_remaining(s->s3->rcontent) == 0) { 11546f7f653bSjsing s->rstate = SSL_ST_READ_HEADER; 1155ee4250f6Sjsing 11566f7f653bSjsing if (s->mode & SSL_MODE_RELEASE_BUFFERS && 115702876cc3Sjsing s->s3->rbuf.left == 0) 11583395f70eSjsing ssl3_release_read_buffer(s); 11593395f70eSjsing } 1160ee4250f6Sjsing 1161ee4250f6Sjsing return ssret; 11623395f70eSjsing } 1163824388bbSjsing 1164ee4250f6Sjsing if (tls_content_type(s->s3->rcontent) == SSL3_RT_ALERT) { 116556fd52a7Sjsing if ((ret = ssl3_read_alert(s)) <= 0) 116656fd52a7Sjsing return ret; 11673395f70eSjsing goto start; 11683395f70eSjsing } 11693395f70eSjsing 11706f7f653bSjsing if (s->shutdown & SSL_SENT_SHUTDOWN) { 11716f7f653bSjsing s->rwstate = SSL_NOTHING; 1172ee4250f6Sjsing tls_content_clear(s->s3->rcontent); 1173ee4250f6Sjsing s->s3->rrec.length = 0; 1174824388bbSjsing return 0; 1175824388bbSjsing } 1176824388bbSjsing 1177ee4250f6Sjsing if (tls_content_type(s->s3->rcontent) == SSL3_RT_APPLICATION_DATA) { 1178824388bbSjsing /* 1179824388bbSjsing * At this point, we were expecting handshake data, but have 1180824388bbSjsing * application data. If the library was running inside 1181824388bbSjsing * ssl3_read() (i.e. in_read_app_data is set) and it makes 1182824388bbSjsing * sense to read application data at this point (session 1183824388bbSjsing * renegotiation not yet started), we will indulge it. 1184824388bbSjsing */ 1185824388bbSjsing if (s->s3->in_read_app_data != 0 && 1186824388bbSjsing s->s3->total_renegotiations != 0 && 1187824388bbSjsing (((s->s3->hs.state & SSL_ST_CONNECT) && 1188824388bbSjsing (s->s3->hs.state >= SSL3_ST_CW_CLNT_HELLO_A) && 1189824388bbSjsing (s->s3->hs.state <= SSL3_ST_CR_SRVR_HELLO_A)) || ( 1190824388bbSjsing (s->s3->hs.state & SSL_ST_ACCEPT) && 1191824388bbSjsing (s->s3->hs.state <= SSL3_ST_SW_HELLO_REQ_A) && 1192824388bbSjsing (s->s3->hs.state >= SSL3_ST_SR_CLNT_HELLO_A)))) { 1193824388bbSjsing s->s3->in_read_app_data = 2; 1194824388bbSjsing return -1; 1195824388bbSjsing } else { 1196824388bbSjsing SSLerror(s, SSL_R_UNEXPECTED_RECORD); 1197824388bbSjsing ssl3_send_alert(s, SSL3_AL_FATAL, 1198824388bbSjsing SSL_AD_UNEXPECTED_MESSAGE); 1199824388bbSjsing return -1; 1200824388bbSjsing } 12013395f70eSjsing } 12023395f70eSjsing 1203ee4250f6Sjsing if (tls_content_type(s->s3->rcontent) == SSL3_RT_CHANGE_CIPHER_SPEC) { 1204b23067a6Sjsing if ((ret = ssl3_read_change_cipher_spec(s)) <= 0) 1205b23067a6Sjsing return ret; 12063395f70eSjsing goto start; 12073395f70eSjsing } 12083395f70eSjsing 1209ee4250f6Sjsing if (tls_content_type(s->s3->rcontent) == SSL3_RT_HANDSHAKE) { 1210225d6b92Sjsing if ((ret = ssl3_read_handshake_unexpected(s)) <= 0) 1211225d6b92Sjsing return ret; 12123395f70eSjsing goto start; 12133395f70eSjsing } 12143395f70eSjsing 12153395f70eSjsing /* 1216824388bbSjsing * Unknown record type - TLSv1.2 sends an unexpected message alert while 1217824388bbSjsing * earlier versions silently ignore the record. 12183395f70eSjsing */ 1219824388bbSjsing if (ssl_effective_tls_version(s) <= TLS1_1_VERSION) { 1220ee4250f6Sjsing tls_content_clear(s->s3->rcontent); 12213395f70eSjsing goto start; 12223395f70eSjsing } 1223c9d7abb7Sbeck SSLerror(s, SSL_R_UNEXPECTED_RECORD); 1224824388bbSjsing ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); 1225824388bbSjsing return -1; 12263395f70eSjsing } 12273395f70eSjsing 12283395f70eSjsing int 12293395f70eSjsing ssl3_do_change_cipher_spec(SSL *s) 12303395f70eSjsing { 123102876cc3Sjsing if (s->s3->hs.tls12.key_block == NULL) { 12323395f70eSjsing if (s->session == NULL || s->session->master_key_length == 0) { 12333395f70eSjsing /* might happen if dtls1_read_bytes() calls this */ 1234c9d7abb7Sbeck SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); 12353395f70eSjsing return (0); 12363395f70eSjsing } 12373395f70eSjsing 1238*f4fe6251Sjsing s->session->cipher_value = s->s3->hs.cipher->value; 1239387303bbSjsing 124053f78dfdSjsing if (!tls1_setup_key_block(s)) 12413395f70eSjsing return (0); 12423395f70eSjsing } 12433395f70eSjsing 1244b3d9ef4bSjsing if (!tls1_change_read_cipher_state(s)) 12453395f70eSjsing return (0); 12463395f70eSjsing 1247643d65b6Sjsing /* 1248643d65b6Sjsing * We have to record the message digest at this point so we can get it 1249643d65b6Sjsing * before we read the finished message. 1250643d65b6Sjsing */ 1251643d65b6Sjsing if (!tls12_derive_peer_finished(s)) 1252643d65b6Sjsing return (0); 12533395f70eSjsing 12543395f70eSjsing return (1); 12553395f70eSjsing } 12563395f70eSjsing 1257e3dbb073Sjsing static int 1258e3dbb073Sjsing ssl3_write_alert(SSL *s) 1259e3dbb073Sjsing { 1260e3dbb073Sjsing if (SSL_is_dtls(s)) 126102876cc3Sjsing return do_dtls1_write(s, SSL3_RT_ALERT, s->s3->send_alert, 126202876cc3Sjsing sizeof(s->s3->send_alert)); 1263e3dbb073Sjsing 126402876cc3Sjsing return do_ssl3_write(s, SSL3_RT_ALERT, s->s3->send_alert, 126502876cc3Sjsing sizeof(s->s3->send_alert)); 1266e3dbb073Sjsing } 1267e3dbb073Sjsing 12683395f70eSjsing int 12693395f70eSjsing ssl3_send_alert(SSL *s, int level, int desc) 12703395f70eSjsing { 1271063f2f30Sjsing /* If alert is fatal, remove session from cache. */ 1272b50283dfSjsing if (level == SSL3_AL_FATAL) 12733395f70eSjsing SSL_CTX_remove_session(s->ctx, s->session); 12743395f70eSjsing 127502876cc3Sjsing s->s3->alert_dispatch = 1; 127602876cc3Sjsing s->s3->send_alert[0] = level; 127702876cc3Sjsing s->s3->send_alert[1] = desc; 12783395f70eSjsing 1279063f2f30Sjsing /* 1280063f2f30Sjsing * If data is still being written out, the alert will be dispatched at 1281063f2f30Sjsing * some point in the future. 1282063f2f30Sjsing */ 128302876cc3Sjsing if (s->s3->wbuf.left != 0) 12843395f70eSjsing return -1; 1285063f2f30Sjsing 1286063f2f30Sjsing return ssl3_dispatch_alert(s); 12873395f70eSjsing } 12883395f70eSjsing 12893395f70eSjsing int 12903395f70eSjsing ssl3_dispatch_alert(SSL *s) 12913395f70eSjsing { 1292063f2f30Sjsing int ret; 12933395f70eSjsing 129402876cc3Sjsing s->s3->alert_dispatch = 0; 1295063f2f30Sjsing if ((ret = ssl3_write_alert(s)) <= 0) { 129602876cc3Sjsing s->s3->alert_dispatch = 1; 1297063f2f30Sjsing return ret; 1298063f2f30Sjsing } 1299063f2f30Sjsing 1300063f2f30Sjsing /* 1301063f2f30Sjsing * Alert sent to BIO. If it is important, flush it now. 13023395f70eSjsing * If the message does not get sent due to non-blocking IO, 1303063f2f30Sjsing * we will not worry too much. 1304063f2f30Sjsing */ 130502876cc3Sjsing if (s->s3->send_alert[0] == SSL3_AL_FATAL) 13063395f70eSjsing (void)BIO_flush(s->wbio); 13073395f70eSjsing 130802876cc3Sjsing ssl_msg_callback(s, 1, SSL3_RT_ALERT, s->s3->send_alert, 2); 13093395f70eSjsing 1310545b2b63Sjsing ssl_info_callback(s, SSL_CB_WRITE_ALERT, 131102876cc3Sjsing (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]); 13123395f70eSjsing 1313063f2f30Sjsing return ret; 13143395f70eSjsing } 1315