xref: /dflybsd-src/crypto/libressl/ssl/ssl_pkt.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: ssl_pkt.c,v 1.60 2022/09/11 13:51:25 jsing Exp $ */
272c33676SMaxim Ag /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
372c33676SMaxim Ag  * All rights reserved.
472c33676SMaxim Ag  *
572c33676SMaxim Ag  * This package is an SSL implementation written
672c33676SMaxim Ag  * by Eric Young (eay@cryptsoft.com).
772c33676SMaxim Ag  * The implementation was written so as to conform with Netscapes SSL.
872c33676SMaxim Ag  *
972c33676SMaxim Ag  * This library is free for commercial and non-commercial use as long as
1072c33676SMaxim Ag  * the following conditions are aheared to.  The following conditions
1172c33676SMaxim Ag  * apply to all code found in this distribution, be it the RC4, RSA,
1272c33676SMaxim Ag  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1372c33676SMaxim Ag  * included with this distribution is covered by the same copyright terms
1472c33676SMaxim Ag  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1572c33676SMaxim Ag  *
1672c33676SMaxim Ag  * Copyright remains Eric Young's, and as such any Copyright notices in
1772c33676SMaxim Ag  * the code are not to be removed.
1872c33676SMaxim Ag  * If this package is used in a product, Eric Young should be given attribution
1972c33676SMaxim Ag  * as the author of the parts of the library used.
2072c33676SMaxim Ag  * This can be in the form of a textual message at program startup or
2172c33676SMaxim Ag  * in documentation (online or textual) provided with the package.
2272c33676SMaxim Ag  *
2372c33676SMaxim Ag  * Redistribution and use in source and binary forms, with or without
2472c33676SMaxim Ag  * modification, are permitted provided that the following conditions
2572c33676SMaxim Ag  * are met:
2672c33676SMaxim Ag  * 1. Redistributions of source code must retain the copyright
2772c33676SMaxim Ag  *    notice, this list of conditions and the following disclaimer.
2872c33676SMaxim Ag  * 2. Redistributions in binary form must reproduce the above copyright
2972c33676SMaxim Ag  *    notice, this list of conditions and the following disclaimer in the
3072c33676SMaxim Ag  *    documentation and/or other materials provided with the distribution.
3172c33676SMaxim Ag  * 3. All advertising materials mentioning features or use of this software
3272c33676SMaxim Ag  *    must display the following acknowledgement:
3372c33676SMaxim Ag  *    "This product includes cryptographic software written by
3472c33676SMaxim Ag  *     Eric Young (eay@cryptsoft.com)"
3572c33676SMaxim Ag  *    The word 'cryptographic' can be left out if the rouines from the library
3672c33676SMaxim Ag  *    being used are not cryptographic related :-).
3772c33676SMaxim Ag  * 4. If you include any Windows specific code (or a derivative thereof) from
3872c33676SMaxim Ag  *    the apps directory (application code) you must include an acknowledgement:
3972c33676SMaxim Ag  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4072c33676SMaxim Ag  *
4172c33676SMaxim Ag  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4272c33676SMaxim Ag  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4372c33676SMaxim Ag  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4472c33676SMaxim Ag  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4572c33676SMaxim Ag  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4672c33676SMaxim Ag  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4772c33676SMaxim Ag  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4872c33676SMaxim Ag  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4972c33676SMaxim Ag  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5072c33676SMaxim Ag  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5172c33676SMaxim Ag  * SUCH DAMAGE.
5272c33676SMaxim Ag  *
5372c33676SMaxim Ag  * The licence and distribution terms for any publically available version or
5472c33676SMaxim Ag  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5572c33676SMaxim Ag  * copied and put under another distribution licence
5672c33676SMaxim Ag  * [including the GNU Public Licence.]
5772c33676SMaxim Ag  */
5872c33676SMaxim Ag /* ====================================================================
5972c33676SMaxim Ag  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
6072c33676SMaxim Ag  *
6172c33676SMaxim Ag  * Redistribution and use in source and binary forms, with or without
6272c33676SMaxim Ag  * modification, are permitted provided that the following conditions
6372c33676SMaxim Ag  * are met:
6472c33676SMaxim Ag  *
6572c33676SMaxim Ag  * 1. Redistributions of source code must retain the above copyright
6672c33676SMaxim Ag  *    notice, this list of conditions and the following disclaimer.
6772c33676SMaxim Ag  *
6872c33676SMaxim Ag  * 2. Redistributions in binary form must reproduce the above copyright
6972c33676SMaxim Ag  *    notice, this list of conditions and the following disclaimer in
7072c33676SMaxim Ag  *    the documentation and/or other materials provided with the
7172c33676SMaxim Ag  *    distribution.
7272c33676SMaxim Ag  *
7372c33676SMaxim Ag  * 3. All advertising materials mentioning features or use of this
7472c33676SMaxim Ag  *    software must display the following acknowledgment:
7572c33676SMaxim Ag  *    "This product includes software developed by the OpenSSL Project
7672c33676SMaxim Ag  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
7772c33676SMaxim Ag  *
7872c33676SMaxim Ag  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
7972c33676SMaxim Ag  *    endorse or promote products derived from this software without
8072c33676SMaxim Ag  *    prior written permission. For written permission, please contact
8172c33676SMaxim Ag  *    openssl-core@openssl.org.
8272c33676SMaxim Ag  *
8372c33676SMaxim Ag  * 5. Products derived from this software may not be called "OpenSSL"
8472c33676SMaxim Ag  *    nor may "OpenSSL" appear in their names without prior written
8572c33676SMaxim Ag  *    permission of the OpenSSL Project.
8672c33676SMaxim Ag  *
8772c33676SMaxim Ag  * 6. Redistributions of any form whatsoever must retain the following
8872c33676SMaxim Ag  *    acknowledgment:
8972c33676SMaxim Ag  *    "This product includes software developed by the OpenSSL Project
9072c33676SMaxim Ag  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
9172c33676SMaxim Ag  *
9272c33676SMaxim Ag  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9372c33676SMaxim Ag  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9472c33676SMaxim Ag  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9572c33676SMaxim Ag  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9672c33676SMaxim Ag  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9772c33676SMaxim Ag  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9872c33676SMaxim Ag  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9972c33676SMaxim Ag  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10072c33676SMaxim Ag  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10172c33676SMaxim Ag  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10272c33676SMaxim Ag  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10372c33676SMaxim Ag  * OF THE POSSIBILITY OF SUCH DAMAGE.
10472c33676SMaxim Ag  * ====================================================================
10572c33676SMaxim Ag  *
10672c33676SMaxim Ag  * This product includes cryptographic software written by Eric Young
10772c33676SMaxim Ag  * (eay@cryptsoft.com).  This product includes software written by Tim
10872c33676SMaxim Ag  * Hudson (tjh@cryptsoft.com).
10972c33676SMaxim Ag  *
11072c33676SMaxim Ag  */
11172c33676SMaxim Ag 
11272c33676SMaxim Ag #include <errno.h>
11372c33676SMaxim Ag #include <stdio.h>
11472c33676SMaxim Ag 
11572c33676SMaxim Ag #include <openssl/buffer.h>
11672c33676SMaxim Ag #include <openssl/evp.h>
11772c33676SMaxim Ag 
11872c33676SMaxim Ag #include "bytestring.h"
119*de0e0e4dSAntonio Huete Jimenez #include "dtls_locl.h"
120*de0e0e4dSAntonio Huete Jimenez #include "ssl_locl.h"
12172c33676SMaxim Ag 
12272c33676SMaxim Ag static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
123cca6fc52SDaniel Fojt     unsigned int len);
12472c33676SMaxim Ag static int ssl3_get_record(SSL *s);
12572c33676SMaxim Ag 
12672c33676SMaxim Ag /*
12772c33676SMaxim Ag  * Force a WANT_READ return for certain error conditions where
12872c33676SMaxim Ag  * we don't want to spin internally.
12972c33676SMaxim Ag  */
130*de0e0e4dSAntonio Huete Jimenez void
ssl_force_want_read(SSL * s)13172c33676SMaxim Ag ssl_force_want_read(SSL *s)
13272c33676SMaxim Ag {
13372c33676SMaxim Ag 	BIO *bio;
13472c33676SMaxim Ag 
13572c33676SMaxim Ag 	bio = SSL_get_rbio(s);
13672c33676SMaxim Ag 	BIO_clear_retry_flags(bio);
13772c33676SMaxim Ag 	BIO_set_retry_read(bio);
138*de0e0e4dSAntonio Huete Jimenez 
13972c33676SMaxim Ag 	s->internal->rwstate = SSL_READING;
14072c33676SMaxim Ag }
14172c33676SMaxim Ag 
14272c33676SMaxim Ag /*
14372c33676SMaxim Ag  * If extend == 0, obtain new n-byte packet; if extend == 1, increase
14472c33676SMaxim Ag  * packet by another n bytes.
145*de0e0e4dSAntonio Huete Jimenez  * The packet will be in the sub-array of s->s3->rbuf.buf specified
14672c33676SMaxim Ag  * by s->internal->packet and s->internal->packet_length.
14772c33676SMaxim Ag  * (If s->internal->read_ahead is set, 'max' bytes may be stored in rbuf
14872c33676SMaxim Ag  * [plus s->internal->packet_length bytes if extend == 1].)
14972c33676SMaxim Ag  */
15072c33676SMaxim Ag static int
ssl3_read_n(SSL * s,int n,int max,int extend)15172c33676SMaxim Ag ssl3_read_n(SSL *s, int n, int max, int extend)
15272c33676SMaxim Ag {
153*de0e0e4dSAntonio Huete Jimenez 	SSL3_BUFFER_INTERNAL *rb = &(s->s3->rbuf);
15472c33676SMaxim Ag 	int i, len, left;
15572c33676SMaxim Ag 	size_t align;
15672c33676SMaxim Ag 	unsigned char *pkt;
15772c33676SMaxim Ag 
15872c33676SMaxim Ag 	if (n <= 0)
15972c33676SMaxim Ag 		return n;
16072c33676SMaxim Ag 
16172c33676SMaxim Ag 	if (rb->buf == NULL)
16272c33676SMaxim Ag 		if (!ssl3_setup_read_buffer(s))
16372c33676SMaxim Ag 			return -1;
16472c33676SMaxim Ag 
16572c33676SMaxim Ag 	left = rb->left;
16672c33676SMaxim Ag 	align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH;
16772c33676SMaxim Ag 	align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
16872c33676SMaxim Ag 
16972c33676SMaxim Ag 	if (!extend) {
17072c33676SMaxim Ag 		/* start with empty packet ... */
17172c33676SMaxim Ag 		if (left == 0)
17272c33676SMaxim Ag 			rb->offset = align;
17372c33676SMaxim Ag 		else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) {
17472c33676SMaxim Ag 			/* check if next packet length is large
17572c33676SMaxim Ag 			 * enough to justify payload alignment... */
17672c33676SMaxim Ag 			pkt = rb->buf + rb->offset;
17772c33676SMaxim Ag 			if (pkt[0] == SSL3_RT_APPLICATION_DATA &&
17872c33676SMaxim Ag 			    (pkt[3]<<8|pkt[4]) >= 128) {
17972c33676SMaxim Ag 				/* Note that even if packet is corrupted
18072c33676SMaxim Ag 				 * and its length field is insane, we can
18172c33676SMaxim Ag 				 * only be led to wrong decision about
18272c33676SMaxim Ag 				 * whether memmove will occur or not.
18372c33676SMaxim Ag 				 * Header values has no effect on memmove
18472c33676SMaxim Ag 				 * arguments and therefore no buffer
18572c33676SMaxim Ag 				 * overrun can be triggered. */
18672c33676SMaxim Ag 				memmove(rb->buf + align, pkt, left);
18772c33676SMaxim Ag 				rb->offset = align;
18872c33676SMaxim Ag 			}
18972c33676SMaxim Ag 		}
19072c33676SMaxim Ag 		s->internal->packet = rb->buf + rb->offset;
19172c33676SMaxim Ag 		s->internal->packet_length = 0;
19272c33676SMaxim Ag 		/* ... now we can act as if 'extend' was set */
19372c33676SMaxim Ag 	}
19472c33676SMaxim Ag 
19572c33676SMaxim Ag 	/* For DTLS/UDP reads should not span multiple packets
19672c33676SMaxim Ag 	 * because the read operation returns the whole packet
19772c33676SMaxim Ag 	 * at once (as long as it fits into the buffer). */
198*de0e0e4dSAntonio Huete Jimenez 	if (SSL_is_dtls(s)) {
19972c33676SMaxim Ag 		if (left > 0 && n > left)
20072c33676SMaxim Ag 			n = left;
20172c33676SMaxim Ag 	}
20272c33676SMaxim Ag 
20372c33676SMaxim Ag 	/* if there is enough in the buffer from a previous read, take some */
20472c33676SMaxim Ag 	if (left >= n) {
20572c33676SMaxim Ag 		s->internal->packet_length += n;
20672c33676SMaxim Ag 		rb->left = left - n;
20772c33676SMaxim Ag 		rb->offset += n;
20872c33676SMaxim Ag 		return (n);
20972c33676SMaxim Ag 	}
21072c33676SMaxim Ag 
21172c33676SMaxim Ag 	/* else we need to read more data */
21272c33676SMaxim Ag 
21372c33676SMaxim Ag 	len = s->internal->packet_length;
21472c33676SMaxim Ag 	pkt = rb->buf + align;
21572c33676SMaxim Ag 	/* Move any available bytes to front of buffer:
21672c33676SMaxim Ag 	 * 'len' bytes already pointed to by 'packet',
21772c33676SMaxim Ag 	 * 'left' extra ones at the end */
21872c33676SMaxim Ag 	if (s->internal->packet != pkt)  {
21972c33676SMaxim Ag 		/* len > 0 */
22072c33676SMaxim Ag 		memmove(pkt, s->internal->packet, len + left);
22172c33676SMaxim Ag 		s->internal->packet = pkt;
22272c33676SMaxim Ag 		rb->offset = len + align;
22372c33676SMaxim Ag 	}
22472c33676SMaxim Ag 
22572c33676SMaxim Ag 	if (n > (int)(rb->len - rb->offset)) {
22672c33676SMaxim Ag 		/* does not happen */
22772c33676SMaxim Ag 		SSLerror(s, ERR_R_INTERNAL_ERROR);
22872c33676SMaxim Ag 		return -1;
22972c33676SMaxim Ag 	}
23072c33676SMaxim Ag 
231*de0e0e4dSAntonio Huete Jimenez 	if (s->internal->read_ahead || SSL_is_dtls(s)) {
23272c33676SMaxim Ag 		if (max < n)
23372c33676SMaxim Ag 			max = n;
23472c33676SMaxim Ag 		if (max > (int)(rb->len - rb->offset))
23572c33676SMaxim Ag 			max = rb->len - rb->offset;
236*de0e0e4dSAntonio Huete Jimenez 	} else {
237*de0e0e4dSAntonio Huete Jimenez 		/* ignore max parameter */
238*de0e0e4dSAntonio Huete Jimenez 		max = n;
23972c33676SMaxim Ag 	}
24072c33676SMaxim Ag 
24172c33676SMaxim Ag 	while (left < n) {
242*de0e0e4dSAntonio Huete Jimenez 		/* Now we have len+left bytes at the front of s->s3->rbuf.buf
24372c33676SMaxim Ag 		 * and need to read in more until we have len+n (up to
24472c33676SMaxim Ag 		 * len+max if possible) */
24572c33676SMaxim Ag 
24672c33676SMaxim Ag 		errno = 0;
24772c33676SMaxim Ag 		if (s->rbio != NULL) {
24872c33676SMaxim Ag 			s->internal->rwstate = SSL_READING;
24972c33676SMaxim Ag 			i = BIO_read(s->rbio, pkt + len + left, max - left);
25072c33676SMaxim Ag 		} else {
25172c33676SMaxim Ag 			SSLerror(s, SSL_R_READ_BIO_NOT_SET);
25272c33676SMaxim Ag 			i = -1;
25372c33676SMaxim Ag 		}
25472c33676SMaxim Ag 
25572c33676SMaxim Ag 		if (i <= 0) {
25672c33676SMaxim Ag 			rb->left = left;
25772c33676SMaxim Ag 			if (s->internal->mode & SSL_MODE_RELEASE_BUFFERS &&
258*de0e0e4dSAntonio Huete Jimenez 			    !SSL_is_dtls(s)) {
25972c33676SMaxim Ag 				if (len + left == 0)
26072c33676SMaxim Ag 					ssl3_release_read_buffer(s);
26172c33676SMaxim Ag 			}
26272c33676SMaxim Ag 			return (i);
26372c33676SMaxim Ag 		}
26472c33676SMaxim Ag 		left += i;
26572c33676SMaxim Ag 
26672c33676SMaxim Ag 		/*
26772c33676SMaxim Ag 		 * reads should *never* span multiple packets for DTLS because
26872c33676SMaxim Ag 		 * the underlying transport protocol is message oriented as
26972c33676SMaxim Ag 		 * opposed to byte oriented as in the TLS case.
27072c33676SMaxim Ag 		 */
271*de0e0e4dSAntonio Huete Jimenez 		if (SSL_is_dtls(s)) {
27272c33676SMaxim Ag 			if (n > left)
27372c33676SMaxim Ag 				n = left; /* makes the while condition false */
27472c33676SMaxim Ag 		}
27572c33676SMaxim Ag 	}
27672c33676SMaxim Ag 
27772c33676SMaxim Ag 	/* done reading, now the book-keeping */
27872c33676SMaxim Ag 	rb->offset += n;
27972c33676SMaxim Ag 	rb->left = left - n;
28072c33676SMaxim Ag 	s->internal->packet_length += n;
28172c33676SMaxim Ag 	s->internal->rwstate = SSL_NOTHING;
28272c33676SMaxim Ag 
28372c33676SMaxim Ag 	return (n);
28472c33676SMaxim Ag }
28572c33676SMaxim Ag 
28672c33676SMaxim Ag int
ssl3_packet_read(SSL * s,int plen)28772c33676SMaxim Ag ssl3_packet_read(SSL *s, int plen)
28872c33676SMaxim Ag {
28972c33676SMaxim Ag 	int n;
29072c33676SMaxim Ag 
291*de0e0e4dSAntonio Huete Jimenez 	n = ssl3_read_n(s, plen, s->s3->rbuf.len, 0);
29272c33676SMaxim Ag 	if (n <= 0)
29372c33676SMaxim Ag 		return n;
29472c33676SMaxim Ag 	if (s->internal->packet_length < plen)
29572c33676SMaxim Ag 		return s->internal->packet_length;
29672c33676SMaxim Ag 
29772c33676SMaxim Ag 	return plen;
29872c33676SMaxim Ag }
29972c33676SMaxim Ag 
30072c33676SMaxim Ag int
ssl3_packet_extend(SSL * s,int plen)30172c33676SMaxim Ag ssl3_packet_extend(SSL *s, int plen)
30272c33676SMaxim Ag {
30372c33676SMaxim Ag 	int rlen, n;
30472c33676SMaxim Ag 
30572c33676SMaxim Ag 	if (s->internal->packet_length >= plen)
30672c33676SMaxim Ag 		return plen;
30772c33676SMaxim Ag 	rlen = plen - s->internal->packet_length;
30872c33676SMaxim Ag 
30972c33676SMaxim Ag 	n = ssl3_read_n(s, rlen, rlen, 1);
31072c33676SMaxim Ag 	if (n <= 0)
31172c33676SMaxim Ag 		return n;
31272c33676SMaxim Ag 	if (s->internal->packet_length < plen)
31372c33676SMaxim Ag 		return s->internal->packet_length;
31472c33676SMaxim Ag 
31572c33676SMaxim Ag 	return plen;
31672c33676SMaxim Ag }
31772c33676SMaxim Ag 
31872c33676SMaxim Ag /* Call this to get a new input record.
31972c33676SMaxim Ag  * It will return <= 0 if more data is needed, normally due to an error
32072c33676SMaxim Ag  * or non-blocking IO.
32172c33676SMaxim Ag  * When it finishes, one packet has been decoded and can be found in
32272c33676SMaxim Ag  * ssl->s3->internal->rrec.type    - is the type of record
32372c33676SMaxim Ag  * ssl->s3->internal->rrec.data, 	 - data
32472c33676SMaxim Ag  * ssl->s3->internal->rrec.length, - number of bytes
32572c33676SMaxim Ag  */
32672c33676SMaxim Ag /* used only by ssl3_read_bytes */
32772c33676SMaxim Ag static int
ssl3_get_record(SSL * s)32872c33676SMaxim Ag ssl3_get_record(SSL *s)
32972c33676SMaxim Ag {
330*de0e0e4dSAntonio Huete Jimenez 	SSL3_BUFFER_INTERNAL *rb = &(s->s3->rbuf);
331*de0e0e4dSAntonio Huete Jimenez 	SSL3_RECORD_INTERNAL *rr = &(s->s3->rrec);
332*de0e0e4dSAntonio Huete Jimenez 	uint8_t alert_desc;
333*de0e0e4dSAntonio Huete Jimenez 	uint8_t *out;
334*de0e0e4dSAntonio Huete Jimenez 	size_t out_len;
335*de0e0e4dSAntonio Huete Jimenez 	int al, n;
336*de0e0e4dSAntonio Huete Jimenez 	int ret = -1;
33772c33676SMaxim Ag 
33872c33676SMaxim Ag  again:
33972c33676SMaxim Ag 	/* check if we have the header */
34072c33676SMaxim Ag 	if ((s->internal->rstate != SSL_ST_READ_BODY) ||
34172c33676SMaxim Ag 	    (s->internal->packet_length < SSL3_RT_HEADER_LENGTH)) {
34272c33676SMaxim Ag 		CBS header;
34372c33676SMaxim Ag 		uint16_t len, ssl_version;
34472c33676SMaxim Ag 		uint8_t type;
34572c33676SMaxim Ag 
34672c33676SMaxim Ag 		n = ssl3_packet_read(s, SSL3_RT_HEADER_LENGTH);
34772c33676SMaxim Ag 		if (n <= 0)
34872c33676SMaxim Ag 			return (n);
34972c33676SMaxim Ag 
35072c33676SMaxim Ag 		s->internal->mac_packet = 1;
35172c33676SMaxim Ag 		s->internal->rstate = SSL_ST_READ_BODY;
35272c33676SMaxim Ag 
35372c33676SMaxim Ag 		if (s->server && s->internal->first_packet) {
35472c33676SMaxim Ag 			if ((ret = ssl_server_legacy_first_packet(s)) != 1)
35572c33676SMaxim Ag 				return (ret);
35672c33676SMaxim Ag 			ret = -1;
35772c33676SMaxim Ag 		}
35872c33676SMaxim Ag 
35972c33676SMaxim Ag 		CBS_init(&header, s->internal->packet, SSL3_RT_HEADER_LENGTH);
36072c33676SMaxim Ag 
361cca6fc52SDaniel Fojt 		/* Pull apart the header into the SSL3_RECORD_INTERNAL */
36272c33676SMaxim Ag 		if (!CBS_get_u8(&header, &type) ||
36372c33676SMaxim Ag 		    !CBS_get_u16(&header, &ssl_version) ||
36472c33676SMaxim Ag 		    !CBS_get_u16(&header, &len)) {
36572c33676SMaxim Ag 			SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
36672c33676SMaxim Ag 			goto err;
36772c33676SMaxim Ag 		}
36872c33676SMaxim Ag 
36972c33676SMaxim Ag 		rr->type = type;
37072c33676SMaxim Ag 		rr->length = len;
37172c33676SMaxim Ag 
37272c33676SMaxim Ag 		/* Lets check version */
37372c33676SMaxim Ag 		if (!s->internal->first_packet && ssl_version != s->version) {
37472c33676SMaxim Ag 			if ((s->version & 0xFF00) == (ssl_version & 0xFF00) &&
375*de0e0e4dSAntonio Huete Jimenez 			    !tls12_record_layer_write_protected(s->internal->rl)) {
37672c33676SMaxim Ag 				/* Send back error using their minor version number :-) */
37772c33676SMaxim Ag 				s->version = ssl_version;
378*de0e0e4dSAntonio Huete Jimenez 			}
379*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_WRONG_VERSION_NUMBER);
38072c33676SMaxim Ag 			al = SSL_AD_PROTOCOL_VERSION;
381*de0e0e4dSAntonio Huete Jimenez 			goto fatal_err;
38272c33676SMaxim Ag 		}
38372c33676SMaxim Ag 
38472c33676SMaxim Ag 		if ((ssl_version >> 8) != SSL3_VERSION_MAJOR) {
38572c33676SMaxim Ag 			SSLerror(s, SSL_R_WRONG_VERSION_NUMBER);
38672c33676SMaxim Ag 			goto err;
38772c33676SMaxim Ag 		}
38872c33676SMaxim Ag 
389*de0e0e4dSAntonio Huete Jimenez 		if (rr->length > rb->len - SSL3_RT_HEADER_LENGTH) {
39072c33676SMaxim Ag 			al = SSL_AD_RECORD_OVERFLOW;
39172c33676SMaxim Ag 			SSLerror(s, SSL_R_PACKET_LENGTH_TOO_LONG);
392*de0e0e4dSAntonio Huete Jimenez 			goto fatal_err;
39372c33676SMaxim Ag 		}
39472c33676SMaxim Ag 	}
39572c33676SMaxim Ag 
39672c33676SMaxim Ag 	n = ssl3_packet_extend(s, SSL3_RT_HEADER_LENGTH + rr->length);
39772c33676SMaxim Ag 	if (n <= 0)
39872c33676SMaxim Ag 		return (n);
39972c33676SMaxim Ag 	if (n != SSL3_RT_HEADER_LENGTH + rr->length)
40072c33676SMaxim Ag 		return (n);
40172c33676SMaxim Ag 
40272c33676SMaxim Ag 	s->internal->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
40372c33676SMaxim Ag 
404*de0e0e4dSAntonio Huete Jimenez 	/*
405*de0e0e4dSAntonio Huete Jimenez 	 * A full record has now been read from the wire, which now needs
406*de0e0e4dSAntonio Huete Jimenez 	 * to be processed.
40772c33676SMaxim Ag 	 */
408*de0e0e4dSAntonio Huete Jimenez 	tls12_record_layer_set_version(s->internal->rl, s->version);
40972c33676SMaxim Ag 
410*de0e0e4dSAntonio Huete Jimenez 	if (!tls12_record_layer_open_record(s->internal->rl, s->internal->packet,
411*de0e0e4dSAntonio Huete Jimenez 	    s->internal->packet_length, &out, &out_len)) {
412*de0e0e4dSAntonio Huete Jimenez 		tls12_record_layer_alert(s->internal->rl, &alert_desc);
41372c33676SMaxim Ag 
414*de0e0e4dSAntonio Huete Jimenez 		if (alert_desc == 0)
415*de0e0e4dSAntonio Huete Jimenez 			goto err;
41672c33676SMaxim Ag 
417*de0e0e4dSAntonio Huete Jimenez 		if (alert_desc == SSL_AD_RECORD_OVERFLOW)
41872c33676SMaxim Ag 			SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
419*de0e0e4dSAntonio Huete Jimenez 		else if (alert_desc == SSL_AD_BAD_RECORD_MAC)
42072c33676SMaxim Ag 			SSLerror(s, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
421*de0e0e4dSAntonio Huete Jimenez 
422*de0e0e4dSAntonio Huete Jimenez 		al = alert_desc;
423*de0e0e4dSAntonio Huete Jimenez 		goto fatal_err;
42472c33676SMaxim Ag 	}
42572c33676SMaxim Ag 
426*de0e0e4dSAntonio Huete Jimenez 	rr->data = out;
427*de0e0e4dSAntonio Huete Jimenez 	rr->length = out_len;
42872c33676SMaxim Ag 	rr->off = 0;
42972c33676SMaxim Ag 
43072c33676SMaxim Ag 	/* we have pulled in a full packet so zero things */
43172c33676SMaxim Ag 	s->internal->packet_length = 0;
43272c33676SMaxim Ag 
43372c33676SMaxim Ag 	if (rr->length == 0) {
43472c33676SMaxim Ag 		/*
435*de0e0e4dSAntonio Huete Jimenez 		 * Zero-length fragments are only permitted for application
436*de0e0e4dSAntonio Huete Jimenez 		 * data, as per RFC 5246 section 6.2.1.
437*de0e0e4dSAntonio Huete Jimenez 		 */
438*de0e0e4dSAntonio Huete Jimenez 		if (rr->type != SSL3_RT_APPLICATION_DATA) {
439*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_BAD_LENGTH);
440*de0e0e4dSAntonio Huete Jimenez 			al = SSL_AD_UNEXPECTED_MESSAGE;
441*de0e0e4dSAntonio Huete Jimenez 			goto fatal_err;
442*de0e0e4dSAntonio Huete Jimenez 		}
443*de0e0e4dSAntonio Huete Jimenez 
444*de0e0e4dSAntonio Huete Jimenez 		/*
445*de0e0e4dSAntonio Huete Jimenez 		 * CBC countermeasures for known IV weaknesses can legitimately
446*de0e0e4dSAntonio Huete Jimenez 		 * insert a single empty record, so we allow ourselves to read
447*de0e0e4dSAntonio Huete Jimenez 		 * once past a single empty record without forcing want_read.
44872c33676SMaxim Ag 		 */
44972c33676SMaxim Ag 		if (s->internal->empty_record_count++ > SSL_MAX_EMPTY_RECORDS) {
45072c33676SMaxim Ag 			SSLerror(s, SSL_R_PEER_BEHAVING_BADLY);
45172c33676SMaxim Ag 			return -1;
45272c33676SMaxim Ag 		}
45372c33676SMaxim Ag 		if (s->internal->empty_record_count > 1) {
45472c33676SMaxim Ag 			ssl_force_want_read(s);
45572c33676SMaxim Ag 			return -1;
45672c33676SMaxim Ag 		}
45772c33676SMaxim Ag 		goto again;
45872c33676SMaxim Ag 	}
45972c33676SMaxim Ag 
460*de0e0e4dSAntonio Huete Jimenez 	s->internal->empty_record_count = 0;
461*de0e0e4dSAntonio Huete Jimenez 
46272c33676SMaxim Ag 	return (1);
46372c33676SMaxim Ag 
464*de0e0e4dSAntonio Huete Jimenez  fatal_err:
46572c33676SMaxim Ag 	ssl3_send_alert(s, SSL3_AL_FATAL, al);
46672c33676SMaxim Ag  err:
46772c33676SMaxim Ag 	return (ret);
46872c33676SMaxim Ag }
46972c33676SMaxim Ag 
47072c33676SMaxim Ag /* Call this to write data in records of type 'type'
47172c33676SMaxim Ag  * It will return <= 0 if not all data has been sent or non-blocking IO.
47272c33676SMaxim Ag  */
47372c33676SMaxim Ag int
ssl3_write_bytes(SSL * s,int type,const void * buf_,int len)47472c33676SMaxim Ag ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
47572c33676SMaxim Ag {
47672c33676SMaxim Ag 	const unsigned char *buf = buf_;
47772c33676SMaxim Ag 	unsigned int tot, n, nw;
47872c33676SMaxim Ag 	int i;
47972c33676SMaxim Ag 
48072c33676SMaxim Ag 	if (len < 0) {
48172c33676SMaxim Ag 		SSLerror(s, ERR_R_INTERNAL_ERROR);
48272c33676SMaxim Ag 		return -1;
48372c33676SMaxim Ag 	}
48472c33676SMaxim Ag 
48572c33676SMaxim Ag 	s->internal->rwstate = SSL_NOTHING;
486*de0e0e4dSAntonio Huete Jimenez 	tot = s->s3->wnum;
487*de0e0e4dSAntonio Huete Jimenez 	s->s3->wnum = 0;
48872c33676SMaxim Ag 
48972c33676SMaxim Ag 	if (SSL_in_init(s) && !s->internal->in_handshake) {
49072c33676SMaxim Ag 		i = s->internal->handshake_func(s);
49172c33676SMaxim Ag 		if (i < 0)
49272c33676SMaxim Ag 			return (i);
49372c33676SMaxim Ag 		if (i == 0) {
49472c33676SMaxim Ag 			SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE);
49572c33676SMaxim Ag 			return -1;
49672c33676SMaxim Ag 		}
49772c33676SMaxim Ag 	}
49872c33676SMaxim Ag 
49972c33676SMaxim Ag 	if (len < tot)
50072c33676SMaxim Ag 		len = tot;
50172c33676SMaxim Ag 	n = (len - tot);
50272c33676SMaxim Ag 	for (;;) {
50372c33676SMaxim Ag 		if (n > s->max_send_fragment)
50472c33676SMaxim Ag 			nw = s->max_send_fragment;
50572c33676SMaxim Ag 		else
50672c33676SMaxim Ag 			nw = n;
50772c33676SMaxim Ag 
508cca6fc52SDaniel Fojt 		i = do_ssl3_write(s, type, &(buf[tot]), nw);
50972c33676SMaxim Ag 		if (i <= 0) {
510*de0e0e4dSAntonio Huete Jimenez 			s->s3->wnum = tot;
51172c33676SMaxim Ag 			return i;
51272c33676SMaxim Ag 		}
51372c33676SMaxim Ag 
51472c33676SMaxim Ag 		if ((i == (int)n) || (type == SSL3_RT_APPLICATION_DATA &&
51572c33676SMaxim Ag 		    (s->internal->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
51672c33676SMaxim Ag 			/*
51772c33676SMaxim Ag 			 * Next chunk of data should get another prepended
51872c33676SMaxim Ag 			 * empty fragment in ciphersuites with known-IV
51972c33676SMaxim Ag 			 * weakness.
52072c33676SMaxim Ag 			 */
521*de0e0e4dSAntonio Huete Jimenez 			s->s3->empty_fragment_done = 0;
52272c33676SMaxim Ag 
52372c33676SMaxim Ag 			return tot + i;
52472c33676SMaxim Ag 		}
52572c33676SMaxim Ag 
52672c33676SMaxim Ag 		n -= i;
52772c33676SMaxim Ag 		tot += i;
52872c33676SMaxim Ag 	}
52972c33676SMaxim Ag }
53072c33676SMaxim Ag 
53172c33676SMaxim Ag static int
do_ssl3_write(SSL * s,int type,const unsigned char * buf,unsigned int len)5328edacedfSDaniel Fojt do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
53372c33676SMaxim Ag {
534*de0e0e4dSAntonio Huete Jimenez 	SSL3_BUFFER_INTERNAL *wb = &(s->s3->wbuf);
535cca6fc52SDaniel Fojt 	SSL_SESSION *sess = s->session;
5368edacedfSDaniel Fojt 	int need_empty_fragment = 0;
5378edacedfSDaniel Fojt 	size_t align, out_len;
538cca6fc52SDaniel Fojt 	uint16_t version;
539cca6fc52SDaniel Fojt 	CBB cbb;
5408edacedfSDaniel Fojt 	int ret;
54172c33676SMaxim Ag 
542cca6fc52SDaniel Fojt 	memset(&cbb, 0, sizeof(cbb));
54372c33676SMaxim Ag 
5448edacedfSDaniel Fojt 	if (wb->buf == NULL)
5458edacedfSDaniel Fojt 		if (!ssl3_setup_write_buffer(s))
5468edacedfSDaniel Fojt 			return -1;
5478edacedfSDaniel Fojt 
5488edacedfSDaniel Fojt 	/*
5498edacedfSDaniel Fojt 	 * First check if there is a SSL3_BUFFER_INTERNAL still being written
5508edacedfSDaniel Fojt 	 * out.  This will happen with non blocking IO.
5518edacedfSDaniel Fojt 	 */
5528edacedfSDaniel Fojt 	if (wb->left != 0)
5538edacedfSDaniel Fojt 		return (ssl3_write_pending(s, type, buf, len));
5548edacedfSDaniel Fojt 
5558edacedfSDaniel Fojt 	/* If we have an alert to send, let's send it. */
556*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->alert_dispatch) {
557*de0e0e4dSAntonio Huete Jimenez 		if ((ret = ssl3_dispatch_alert(s)) <= 0)
5588edacedfSDaniel Fojt 			return (ret);
5598edacedfSDaniel Fojt 		/* If it went, fall through and send more stuff. */
5608edacedfSDaniel Fojt 
5618edacedfSDaniel Fojt 		/* We may have released our buffer, if so get it again. */
5628edacedfSDaniel Fojt 		if (wb->buf == NULL)
5638edacedfSDaniel Fojt 			if (!ssl3_setup_write_buffer(s))
5648edacedfSDaniel Fojt 				return -1;
56572c33676SMaxim Ag 	}
56672c33676SMaxim Ag 
5678edacedfSDaniel Fojt 	if (len == 0)
5688edacedfSDaniel Fojt 		return 0;
5698edacedfSDaniel Fojt 
57072c33676SMaxim Ag 	/*
571cca6fc52SDaniel Fojt 	 * Some servers hang if initial client hello is larger than 256
572cca6fc52SDaniel Fojt 	 * bytes and record version number > TLS 1.0.
57372c33676SMaxim Ag 	 */
574cca6fc52SDaniel Fojt 	version = s->version;
575*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->hs.state == SSL3_ST_CW_CLNT_HELLO_B &&
576*de0e0e4dSAntonio Huete Jimenez 	    !s->internal->renegotiate &&
577*de0e0e4dSAntonio Huete Jimenez 	    s->s3->hs.our_max_tls_version > TLS1_VERSION)
578cca6fc52SDaniel Fojt 		version = TLS1_VERSION;
57972c33676SMaxim Ag 
580cca6fc52SDaniel Fojt 	/*
581cca6fc52SDaniel Fojt 	 * Countermeasure against known-IV weakness in CBC ciphersuites
5828edacedfSDaniel Fojt 	 * (see http://www.openssl.org/~bodo/tls-cbc.txt). Note that this
5838edacedfSDaniel Fojt 	 * is unnecessary for AEAD.
584cca6fc52SDaniel Fojt 	 */
585*de0e0e4dSAntonio Huete Jimenez 	if (sess != NULL && tls12_record_layer_write_protected(s->internal->rl)) {
586*de0e0e4dSAntonio Huete Jimenez 		if (s->s3->need_empty_fragments &&
587*de0e0e4dSAntonio Huete Jimenez 		    !s->s3->empty_fragment_done &&
5888edacedfSDaniel Fojt 		    type == SSL3_RT_APPLICATION_DATA)
5898edacedfSDaniel Fojt 			need_empty_fragment = 1;
5908edacedfSDaniel Fojt 	}
591cca6fc52SDaniel Fojt 
5928edacedfSDaniel Fojt 	/*
5938edacedfSDaniel Fojt 	 * An extra fragment would be a couple of cipher blocks, which would
5948edacedfSDaniel Fojt 	 * be a multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real
5958edacedfSDaniel Fojt 	 * payload, then we can just simply pretend we have two headers.
5968edacedfSDaniel Fojt 	 */
5978edacedfSDaniel Fojt 	align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH;
5988edacedfSDaniel Fojt 	if (need_empty_fragment)
5998edacedfSDaniel Fojt 		align += SSL3_RT_HEADER_LENGTH;
6008edacedfSDaniel Fojt 	align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
601cca6fc52SDaniel Fojt 	wb->offset = align;
602cca6fc52SDaniel Fojt 
6038edacedfSDaniel Fojt 	if (!CBB_init_fixed(&cbb, wb->buf + align, wb->len - align))
604cca6fc52SDaniel Fojt 		goto err;
605cca6fc52SDaniel Fojt 
6068edacedfSDaniel Fojt 	tls12_record_layer_set_version(s->internal->rl, version);
6078edacedfSDaniel Fojt 
6088edacedfSDaniel Fojt 	if (need_empty_fragment) {
6098edacedfSDaniel Fojt 		if (!tls12_record_layer_seal_record(s->internal->rl, type,
6108edacedfSDaniel Fojt 		    buf, 0, &cbb))
611cca6fc52SDaniel Fojt 			goto err;
612*de0e0e4dSAntonio Huete Jimenez 		s->s3->empty_fragment_done = 1;
613cca6fc52SDaniel Fojt 	}
614cca6fc52SDaniel Fojt 
6158edacedfSDaniel Fojt 	if (!tls12_record_layer_seal_record(s->internal->rl, type, buf, len, &cbb))
616cca6fc52SDaniel Fojt 		goto err;
617cca6fc52SDaniel Fojt 
6188edacedfSDaniel Fojt 	if (!CBB_finish(&cbb, NULL, &out_len))
6198edacedfSDaniel Fojt 		goto err;
62072c33676SMaxim Ag 
6218edacedfSDaniel Fojt 	wb->left = out_len;
6228edacedfSDaniel Fojt 
6238edacedfSDaniel Fojt 	/*
6248edacedfSDaniel Fojt 	 * Memorize arguments so that ssl3_write_pending can detect
6258edacedfSDaniel Fojt 	 * bad write retries later.
6268edacedfSDaniel Fojt 	 */
627*de0e0e4dSAntonio Huete Jimenez 	s->s3->wpend_tot = len;
628*de0e0e4dSAntonio Huete Jimenez 	s->s3->wpend_buf = buf;
629*de0e0e4dSAntonio Huete Jimenez 	s->s3->wpend_type = type;
630*de0e0e4dSAntonio Huete Jimenez 	s->s3->wpend_ret = len;
63172c33676SMaxim Ag 
6328edacedfSDaniel Fojt 	/* We now just need to write the buffer. */
63372c33676SMaxim Ag 	return ssl3_write_pending(s, type, buf, len);
6348edacedfSDaniel Fojt 
63572c33676SMaxim Ag  err:
6368edacedfSDaniel Fojt 	CBB_cleanup(&cbb);
6378edacedfSDaniel Fojt 
63872c33676SMaxim Ag 	return -1;
63972c33676SMaxim Ag }
64072c33676SMaxim Ag 
641*de0e0e4dSAntonio Huete Jimenez /* if s->s3->wbuf.left != 0, we need to call this */
64272c33676SMaxim Ag int
ssl3_write_pending(SSL * s,int type,const unsigned char * buf,unsigned int len)64372c33676SMaxim Ag ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len)
64472c33676SMaxim Ag {
64572c33676SMaxim Ag 	int i;
646*de0e0e4dSAntonio Huete Jimenez 	SSL3_BUFFER_INTERNAL *wb = &(s->s3->wbuf);
64772c33676SMaxim Ag 
64872c33676SMaxim Ag 	/* XXXX */
649*de0e0e4dSAntonio Huete Jimenez 	if ((s->s3->wpend_tot > (int)len) || ((s->s3->wpend_buf != buf) &&
65072c33676SMaxim Ag 	    !(s->internal->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) ||
651*de0e0e4dSAntonio Huete Jimenez 	    (s->s3->wpend_type != type)) {
65272c33676SMaxim Ag 		SSLerror(s, SSL_R_BAD_WRITE_RETRY);
65372c33676SMaxim Ag 		return (-1);
65472c33676SMaxim Ag 	}
65572c33676SMaxim Ag 
65672c33676SMaxim Ag 	for (;;) {
65772c33676SMaxim Ag 		errno = 0;
65872c33676SMaxim Ag 		if (s->wbio != NULL) {
65972c33676SMaxim Ag 			s->internal->rwstate = SSL_WRITING;
6608edacedfSDaniel Fojt 			i = BIO_write(s->wbio, (char *)&(wb->buf[wb->offset]),
66172c33676SMaxim Ag 			    (unsigned int)wb->left);
66272c33676SMaxim Ag 		} else {
66372c33676SMaxim Ag 			SSLerror(s, SSL_R_BIO_NOT_SET);
66472c33676SMaxim Ag 			i = -1;
66572c33676SMaxim Ag 		}
66672c33676SMaxim Ag 		if (i == wb->left) {
66772c33676SMaxim Ag 			wb->left = 0;
66872c33676SMaxim Ag 			wb->offset += i;
66972c33676SMaxim Ag 			if (s->internal->mode & SSL_MODE_RELEASE_BUFFERS &&
670*de0e0e4dSAntonio Huete Jimenez 			    !SSL_is_dtls(s))
67172c33676SMaxim Ag 				ssl3_release_write_buffer(s);
67272c33676SMaxim Ag 			s->internal->rwstate = SSL_NOTHING;
673*de0e0e4dSAntonio Huete Jimenez 			return (s->s3->wpend_ret);
67472c33676SMaxim Ag 		} else if (i <= 0) {
67572c33676SMaxim Ag 			/*
67672c33676SMaxim Ag 			 * For DTLS, just drop it. That's kind of the
67772c33676SMaxim Ag 			 * whole point in using a datagram service.
67872c33676SMaxim Ag 			 */
679*de0e0e4dSAntonio Huete Jimenez 			if (SSL_is_dtls(s))
68072c33676SMaxim Ag 				wb->left = 0;
68172c33676SMaxim Ag 			return (i);
68272c33676SMaxim Ag 		}
68372c33676SMaxim Ag 		wb->offset += i;
68472c33676SMaxim Ag 		wb->left -= i;
68572c33676SMaxim Ag 	}
68672c33676SMaxim Ag }
68772c33676SMaxim Ag 
688*de0e0e4dSAntonio Huete Jimenez int
ssl3_read_alert(SSL * s)689*de0e0e4dSAntonio Huete Jimenez ssl3_read_alert(SSL *s)
690*de0e0e4dSAntonio Huete Jimenez {
691*de0e0e4dSAntonio Huete Jimenez 	SSL3_RECORD_INTERNAL *rr = &s->s3->rrec;
692*de0e0e4dSAntonio Huete Jimenez 	uint8_t alert_level, alert_descr;
693*de0e0e4dSAntonio Huete Jimenez 	CBS cbs;
694*de0e0e4dSAntonio Huete Jimenez 
695*de0e0e4dSAntonio Huete Jimenez 	/*
696*de0e0e4dSAntonio Huete Jimenez 	 * TLSv1.2 permits an alert to be fragmented across multiple records or
697*de0e0e4dSAntonio Huete Jimenez 	 * for multiple alerts to be be coalesced into a single alert record.
698*de0e0e4dSAntonio Huete Jimenez 	 * In the case of DTLS, there is no way to reassemble an alert
699*de0e0e4dSAntonio Huete Jimenez 	 * fragmented across multiple records, hence a full alert must be
700*de0e0e4dSAntonio Huete Jimenez 	 * available in the record.
701*de0e0e4dSAntonio Huete Jimenez 	 */
702*de0e0e4dSAntonio Huete Jimenez 	while (rr->length > 0 &&
703*de0e0e4dSAntonio Huete Jimenez 	    s->s3->alert_fragment_len < sizeof(s->s3->alert_fragment)) {
704*de0e0e4dSAntonio Huete Jimenez 		s->s3->alert_fragment[s->s3->alert_fragment_len++] =
705*de0e0e4dSAntonio Huete Jimenez 		    rr->data[rr->off++];
706*de0e0e4dSAntonio Huete Jimenez 		rr->length--;
707*de0e0e4dSAntonio Huete Jimenez 	}
708*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->alert_fragment_len < sizeof(s->s3->alert_fragment)) {
709*de0e0e4dSAntonio Huete Jimenez 		if (SSL_is_dtls(s)) {
710*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_BAD_LENGTH);
711*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
712*de0e0e4dSAntonio Huete Jimenez 			return -1;
713*de0e0e4dSAntonio Huete Jimenez 		}
714*de0e0e4dSAntonio Huete Jimenez 		return 1;
715*de0e0e4dSAntonio Huete Jimenez 	}
716*de0e0e4dSAntonio Huete Jimenez 
717*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&cbs, s->s3->alert_fragment, sizeof(s->s3->alert_fragment));
718*de0e0e4dSAntonio Huete Jimenez 
719*de0e0e4dSAntonio Huete Jimenez 	ssl_msg_callback_cbs(s, 0, SSL3_RT_ALERT, &cbs);
720*de0e0e4dSAntonio Huete Jimenez 
721*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_u8(&cbs, &alert_level))
722*de0e0e4dSAntonio Huete Jimenez 		return -1;
723*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_u8(&cbs, &alert_descr))
724*de0e0e4dSAntonio Huete Jimenez 		return -1;
725*de0e0e4dSAntonio Huete Jimenez 
726*de0e0e4dSAntonio Huete Jimenez 	s->s3->alert_fragment_len = 0;
727*de0e0e4dSAntonio Huete Jimenez 
728*de0e0e4dSAntonio Huete Jimenez 	ssl_info_callback(s, SSL_CB_READ_ALERT,
729*de0e0e4dSAntonio Huete Jimenez 	    (alert_level << 8) | alert_descr);
730*de0e0e4dSAntonio Huete Jimenez 
731*de0e0e4dSAntonio Huete Jimenez 	if (alert_level == SSL3_AL_WARNING) {
732*de0e0e4dSAntonio Huete Jimenez 		s->s3->warn_alert = alert_descr;
733*de0e0e4dSAntonio Huete Jimenez 		if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
734*de0e0e4dSAntonio Huete Jimenez 			s->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
735*de0e0e4dSAntonio Huete Jimenez 			return 0;
736*de0e0e4dSAntonio Huete Jimenez 		}
737*de0e0e4dSAntonio Huete Jimenez 		/* We requested renegotiation and the peer rejected it. */
738*de0e0e4dSAntonio Huete Jimenez 		if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
739*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_NO_RENEGOTIATION);
740*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL,
741*de0e0e4dSAntonio Huete Jimenez 			    SSL_AD_HANDSHAKE_FAILURE);
742*de0e0e4dSAntonio Huete Jimenez 			return -1;
743*de0e0e4dSAntonio Huete Jimenez 		}
744*de0e0e4dSAntonio Huete Jimenez 	} else if (alert_level == SSL3_AL_FATAL) {
745*de0e0e4dSAntonio Huete Jimenez 		s->internal->rwstate = SSL_NOTHING;
746*de0e0e4dSAntonio Huete Jimenez 		s->s3->fatal_alert = alert_descr;
747*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, SSL_AD_REASON_OFFSET + alert_descr);
748*de0e0e4dSAntonio Huete Jimenez 		ERR_asprintf_error_data("SSL alert number %d", alert_descr);
749*de0e0e4dSAntonio Huete Jimenez 		s->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
750*de0e0e4dSAntonio Huete Jimenez 		SSL_CTX_remove_session(s->ctx, s->session);
751*de0e0e4dSAntonio Huete Jimenez 		return 0;
752*de0e0e4dSAntonio Huete Jimenez 	} else {
753*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, SSL_R_UNKNOWN_ALERT_TYPE);
754*de0e0e4dSAntonio Huete Jimenez 		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
755*de0e0e4dSAntonio Huete Jimenez 		return -1;
756*de0e0e4dSAntonio Huete Jimenez 	}
757*de0e0e4dSAntonio Huete Jimenez 
758*de0e0e4dSAntonio Huete Jimenez 	return 1;
759*de0e0e4dSAntonio Huete Jimenez }
760*de0e0e4dSAntonio Huete Jimenez 
761*de0e0e4dSAntonio Huete Jimenez int
ssl3_read_change_cipher_spec(SSL * s)762*de0e0e4dSAntonio Huete Jimenez ssl3_read_change_cipher_spec(SSL *s)
763*de0e0e4dSAntonio Huete Jimenez {
764*de0e0e4dSAntonio Huete Jimenez 	SSL3_RECORD_INTERNAL *rr = &s->s3->rrec;
765*de0e0e4dSAntonio Huete Jimenez 	const uint8_t ccs[] = { SSL3_MT_CCS };
766*de0e0e4dSAntonio Huete Jimenez 	CBS cbs;
767*de0e0e4dSAntonio Huete Jimenez 
768*de0e0e4dSAntonio Huete Jimenez 	/*
769*de0e0e4dSAntonio Huete Jimenez 	 * 'Change Cipher Spec' is just a single byte, so we know exactly what
770*de0e0e4dSAntonio Huete Jimenez 	 * the record payload has to look like.
771*de0e0e4dSAntonio Huete Jimenez 	 */
772*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&cbs, rr->data, rr->length);
773*de0e0e4dSAntonio Huete Jimenez 	if (rr->off != 0 || CBS_len(&cbs) != sizeof(ccs)) {
774*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC);
775*de0e0e4dSAntonio Huete Jimenez 		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
776*de0e0e4dSAntonio Huete Jimenez 		return -1;
777*de0e0e4dSAntonio Huete Jimenez 	}
778*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_mem_equal(&cbs, ccs, sizeof(ccs))) {
779*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC);
780*de0e0e4dSAntonio Huete Jimenez 		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
781*de0e0e4dSAntonio Huete Jimenez 		return -1;
782*de0e0e4dSAntonio Huete Jimenez 	}
783*de0e0e4dSAntonio Huete Jimenez 
784*de0e0e4dSAntonio Huete Jimenez 	/* XDTLS: check that epoch is consistent */
785*de0e0e4dSAntonio Huete Jimenez 
786*de0e0e4dSAntonio Huete Jimenez 	ssl_msg_callback_cbs(s, 0, SSL3_RT_CHANGE_CIPHER_SPEC, &cbs);
787*de0e0e4dSAntonio Huete Jimenez 
788*de0e0e4dSAntonio Huete Jimenez 	/* Check that we have a cipher to change to. */
789*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->hs.cipher == NULL) {
790*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, SSL_R_CCS_RECEIVED_EARLY);
791*de0e0e4dSAntonio Huete Jimenez 		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
792*de0e0e4dSAntonio Huete Jimenez 		return -1;
793*de0e0e4dSAntonio Huete Jimenez 	}
794*de0e0e4dSAntonio Huete Jimenez 
795*de0e0e4dSAntonio Huete Jimenez 	/* Check that we should be receiving a Change Cipher Spec. */
796*de0e0e4dSAntonio Huete Jimenez 	if (SSL_is_dtls(s)) {
797*de0e0e4dSAntonio Huete Jimenez 		if (!s->d1->change_cipher_spec_ok) {
798*de0e0e4dSAntonio Huete Jimenez 			/*
799*de0e0e4dSAntonio Huete Jimenez 			 * We can't process a CCS now, because previous
800*de0e0e4dSAntonio Huete Jimenez 			 * handshake messages are still missing, so just
801*de0e0e4dSAntonio Huete Jimenez 			 * drop it.
802*de0e0e4dSAntonio Huete Jimenez 			 */
803*de0e0e4dSAntonio Huete Jimenez 			rr->length = 0;
804*de0e0e4dSAntonio Huete Jimenez 			return 1;
805*de0e0e4dSAntonio Huete Jimenez 		}
806*de0e0e4dSAntonio Huete Jimenez 		s->d1->change_cipher_spec_ok = 0;
807*de0e0e4dSAntonio Huete Jimenez 	} else {
808*de0e0e4dSAntonio Huete Jimenez 		if ((s->s3->flags & SSL3_FLAGS_CCS_OK) == 0) {
809*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_CCS_RECEIVED_EARLY);
810*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL,
811*de0e0e4dSAntonio Huete Jimenez 			    SSL_AD_UNEXPECTED_MESSAGE);
812*de0e0e4dSAntonio Huete Jimenez 			return -1;
813*de0e0e4dSAntonio Huete Jimenez 		}
814*de0e0e4dSAntonio Huete Jimenez 		s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
815*de0e0e4dSAntonio Huete Jimenez 	}
816*de0e0e4dSAntonio Huete Jimenez 
817*de0e0e4dSAntonio Huete Jimenez 	rr->length = 0;
818*de0e0e4dSAntonio Huete Jimenez 
819*de0e0e4dSAntonio Huete Jimenez 	s->s3->change_cipher_spec = 1;
820*de0e0e4dSAntonio Huete Jimenez 	if (!ssl3_do_change_cipher_spec(s))
821*de0e0e4dSAntonio Huete Jimenez 		return -1;
822*de0e0e4dSAntonio Huete Jimenez 
823*de0e0e4dSAntonio Huete Jimenez 	return 1;
824*de0e0e4dSAntonio Huete Jimenez }
825*de0e0e4dSAntonio Huete Jimenez 
826*de0e0e4dSAntonio Huete Jimenez static int
ssl3_read_handshake_unexpected(SSL * s)827*de0e0e4dSAntonio Huete Jimenez ssl3_read_handshake_unexpected(SSL *s)
828*de0e0e4dSAntonio Huete Jimenez {
829*de0e0e4dSAntonio Huete Jimenez 	SSL3_RECORD_INTERNAL *rr = &s->s3->rrec;
830*de0e0e4dSAntonio Huete Jimenez 	uint32_t hs_msg_length;
831*de0e0e4dSAntonio Huete Jimenez 	uint8_t hs_msg_type;
832*de0e0e4dSAntonio Huete Jimenez 	CBS cbs;
833*de0e0e4dSAntonio Huete Jimenez 	int ret;
834*de0e0e4dSAntonio Huete Jimenez 
835*de0e0e4dSAntonio Huete Jimenez 	/*
836*de0e0e4dSAntonio Huete Jimenez 	 * We need four bytes of handshake data so we have a handshake message
837*de0e0e4dSAntonio Huete Jimenez 	 * header - this may be in the same record or fragmented across multiple
838*de0e0e4dSAntonio Huete Jimenez 	 * records.
839*de0e0e4dSAntonio Huete Jimenez 	 */
840*de0e0e4dSAntonio Huete Jimenez 	while (rr->length > 0 &&
841*de0e0e4dSAntonio Huete Jimenez 	    s->s3->handshake_fragment_len < sizeof(s->s3->handshake_fragment)) {
842*de0e0e4dSAntonio Huete Jimenez 		s->s3->handshake_fragment[s->s3->handshake_fragment_len++] =
843*de0e0e4dSAntonio Huete Jimenez 		    rr->data[rr->off++];
844*de0e0e4dSAntonio Huete Jimenez 		rr->length--;
845*de0e0e4dSAntonio Huete Jimenez 	}
846*de0e0e4dSAntonio Huete Jimenez 
847*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->handshake_fragment_len < sizeof(s->s3->handshake_fragment))
848*de0e0e4dSAntonio Huete Jimenez 		return 1;
849*de0e0e4dSAntonio Huete Jimenez 
850*de0e0e4dSAntonio Huete Jimenez 	if (s->internal->in_handshake) {
851*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, ERR_R_INTERNAL_ERROR);
852*de0e0e4dSAntonio Huete Jimenez 		return -1;
853*de0e0e4dSAntonio Huete Jimenez 	}
854*de0e0e4dSAntonio Huete Jimenez 
855*de0e0e4dSAntonio Huete Jimenez 	/*
856*de0e0e4dSAntonio Huete Jimenez 	 * This code currently deals with HelloRequest and ClientHello messages -
857*de0e0e4dSAntonio Huete Jimenez 	 * anything else is pushed to the handshake_func. Almost all of this
858*de0e0e4dSAntonio Huete Jimenez 	 * belongs in the client/server handshake code.
859*de0e0e4dSAntonio Huete Jimenez 	 */
860*de0e0e4dSAntonio Huete Jimenez 
861*de0e0e4dSAntonio Huete Jimenez 	/* Parse handshake message header. */
862*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&cbs, s->s3->handshake_fragment, s->s3->handshake_fragment_len);
863*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_u8(&cbs, &hs_msg_type))
864*de0e0e4dSAntonio Huete Jimenez 		return -1;
865*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_u24(&cbs, &hs_msg_length))
866*de0e0e4dSAntonio Huete Jimenez 		return -1;
867*de0e0e4dSAntonio Huete Jimenez 
868*de0e0e4dSAntonio Huete Jimenez 	if (hs_msg_type == SSL3_MT_HELLO_REQUEST) {
869*de0e0e4dSAntonio Huete Jimenez 		/*
870*de0e0e4dSAntonio Huete Jimenez 		 * Incoming HelloRequest messages should only be received by a
871*de0e0e4dSAntonio Huete Jimenez 		 * client. A server may send these at any time - a client should
872*de0e0e4dSAntonio Huete Jimenez 		 * ignore the message if received in the middle of a handshake.
873*de0e0e4dSAntonio Huete Jimenez 		 * See RFC 5246 sections 7.4 and 7.4.1.1.
874*de0e0e4dSAntonio Huete Jimenez 		 */
875*de0e0e4dSAntonio Huete Jimenez 		if (s->server) {
876*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
877*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL,
878*de0e0e4dSAntonio Huete Jimenez 			     SSL_AD_UNEXPECTED_MESSAGE);
879*de0e0e4dSAntonio Huete Jimenez 			return -1;
880*de0e0e4dSAntonio Huete Jimenez 		}
881*de0e0e4dSAntonio Huete Jimenez 
882*de0e0e4dSAntonio Huete Jimenez 		if (hs_msg_length != 0) {
883*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_BAD_HELLO_REQUEST);
884*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
885*de0e0e4dSAntonio Huete Jimenez 			return -1;
886*de0e0e4dSAntonio Huete Jimenez 		}
887*de0e0e4dSAntonio Huete Jimenez 
888*de0e0e4dSAntonio Huete Jimenez 		ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE,
889*de0e0e4dSAntonio Huete Jimenez 		    s->s3->handshake_fragment, s->s3->handshake_fragment_len);
890*de0e0e4dSAntonio Huete Jimenez 
891*de0e0e4dSAntonio Huete Jimenez 		s->s3->handshake_fragment_len = 0;
892*de0e0e4dSAntonio Huete Jimenez 
893*de0e0e4dSAntonio Huete Jimenez 		/*
894*de0e0e4dSAntonio Huete Jimenez 		 * It should be impossible to hit this, but keep the safety
895*de0e0e4dSAntonio Huete Jimenez 		 * harness for now...
896*de0e0e4dSAntonio Huete Jimenez 		 */
897*de0e0e4dSAntonio Huete Jimenez 		if (s->session == NULL || s->session->cipher == NULL)
898*de0e0e4dSAntonio Huete Jimenez 			return 1;
899*de0e0e4dSAntonio Huete Jimenez 
900*de0e0e4dSAntonio Huete Jimenez 		/*
901*de0e0e4dSAntonio Huete Jimenez 		 * Ignore this message if we're currently handshaking,
902*de0e0e4dSAntonio Huete Jimenez 		 * renegotiation is already pending or renegotiation is disabled
903*de0e0e4dSAntonio Huete Jimenez 		 * via flags.
904*de0e0e4dSAntonio Huete Jimenez 		 */
905*de0e0e4dSAntonio Huete Jimenez 		if (!SSL_is_init_finished(s) || s->s3->renegotiate ||
906*de0e0e4dSAntonio Huete Jimenez 		    (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0)
907*de0e0e4dSAntonio Huete Jimenez 			return 1;
908*de0e0e4dSAntonio Huete Jimenez 
909*de0e0e4dSAntonio Huete Jimenez 		if (!ssl3_renegotiate(s))
910*de0e0e4dSAntonio Huete Jimenez 			return 1;
911*de0e0e4dSAntonio Huete Jimenez 		if (!ssl3_renegotiate_check(s))
912*de0e0e4dSAntonio Huete Jimenez 			return 1;
913*de0e0e4dSAntonio Huete Jimenez 
914*de0e0e4dSAntonio Huete Jimenez 	} else if (hs_msg_type == SSL3_MT_CLIENT_HELLO) {
915*de0e0e4dSAntonio Huete Jimenez 		/*
916*de0e0e4dSAntonio Huete Jimenez 		 * Incoming ClientHello messages should only be received by a
917*de0e0e4dSAntonio Huete Jimenez 		 * server. A client may send these in response to server
918*de0e0e4dSAntonio Huete Jimenez 		 * initiated renegotiation (HelloRequest) or in order to
919*de0e0e4dSAntonio Huete Jimenez 		 * initiate renegotiation by the client. See RFC 5246 section
920*de0e0e4dSAntonio Huete Jimenez 		 * 7.4.1.2.
921*de0e0e4dSAntonio Huete Jimenez 		 */
922*de0e0e4dSAntonio Huete Jimenez 		if (!s->server) {
923*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
924*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL,
925*de0e0e4dSAntonio Huete Jimenez 			     SSL_AD_UNEXPECTED_MESSAGE);
926*de0e0e4dSAntonio Huete Jimenez 			return -1;
927*de0e0e4dSAntonio Huete Jimenez 		}
928*de0e0e4dSAntonio Huete Jimenez 
929*de0e0e4dSAntonio Huete Jimenez 		/*
930*de0e0e4dSAntonio Huete Jimenez 		 * A client should not be sending a ClientHello unless we're not
931*de0e0e4dSAntonio Huete Jimenez 		 * currently handshaking.
932*de0e0e4dSAntonio Huete Jimenez 		 */
933*de0e0e4dSAntonio Huete Jimenez 		if (!SSL_is_init_finished(s)) {
934*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
935*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL,
936*de0e0e4dSAntonio Huete Jimenez 			    SSL_AD_UNEXPECTED_MESSAGE);
937*de0e0e4dSAntonio Huete Jimenez 			return -1;
938*de0e0e4dSAntonio Huete Jimenez 		}
939*de0e0e4dSAntonio Huete Jimenez 
940*de0e0e4dSAntonio Huete Jimenez 		if ((s->internal->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0) {
941*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL,
942*de0e0e4dSAntonio Huete Jimenez 			    SSL_AD_NO_RENEGOTIATION);
943*de0e0e4dSAntonio Huete Jimenez 			return -1;
944*de0e0e4dSAntonio Huete Jimenez 		}
945*de0e0e4dSAntonio Huete Jimenez 
946*de0e0e4dSAntonio Huete Jimenez 		if (s->session == NULL || s->session->cipher == NULL) {
947*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, ERR_R_INTERNAL_ERROR);
948*de0e0e4dSAntonio Huete Jimenez 			return -1;
949*de0e0e4dSAntonio Huete Jimenez 		}
950*de0e0e4dSAntonio Huete Jimenez 
951*de0e0e4dSAntonio Huete Jimenez 		/* Client requested renegotiation but it is not permitted. */
952*de0e0e4dSAntonio Huete Jimenez 		if (!s->s3->send_connection_binding ||
953*de0e0e4dSAntonio Huete Jimenez 		    (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) {
954*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_WARNING,
955*de0e0e4dSAntonio Huete Jimenez 			    SSL_AD_NO_RENEGOTIATION);
956*de0e0e4dSAntonio Huete Jimenez 			return 1;
957*de0e0e4dSAntonio Huete Jimenez 		}
958*de0e0e4dSAntonio Huete Jimenez 
959*de0e0e4dSAntonio Huete Jimenez 		s->s3->hs.state = SSL_ST_ACCEPT;
960*de0e0e4dSAntonio Huete Jimenez 		s->internal->renegotiate = 1;
961*de0e0e4dSAntonio Huete Jimenez 		s->internal->new_session = 1;
962*de0e0e4dSAntonio Huete Jimenez 
963*de0e0e4dSAntonio Huete Jimenez 	} else {
964*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
965*de0e0e4dSAntonio Huete Jimenez 		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
966*de0e0e4dSAntonio Huete Jimenez 		return -1;
967*de0e0e4dSAntonio Huete Jimenez 	}
968*de0e0e4dSAntonio Huete Jimenez 
969*de0e0e4dSAntonio Huete Jimenez 	if ((ret = s->internal->handshake_func(s)) < 0)
970*de0e0e4dSAntonio Huete Jimenez 		return ret;
971*de0e0e4dSAntonio Huete Jimenez 	if (ret == 0) {
972*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE);
973*de0e0e4dSAntonio Huete Jimenez 		return -1;
974*de0e0e4dSAntonio Huete Jimenez 	}
975*de0e0e4dSAntonio Huete Jimenez 
976*de0e0e4dSAntonio Huete Jimenez 	if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) {
977*de0e0e4dSAntonio Huete Jimenez 		if (s->s3->rbuf.left == 0) {
978*de0e0e4dSAntonio Huete Jimenez 			ssl_force_want_read(s);
979*de0e0e4dSAntonio Huete Jimenez 			return -1;
980*de0e0e4dSAntonio Huete Jimenez 		}
981*de0e0e4dSAntonio Huete Jimenez 	}
982*de0e0e4dSAntonio Huete Jimenez 
983*de0e0e4dSAntonio Huete Jimenez 	/*
984*de0e0e4dSAntonio Huete Jimenez 	 * We either finished a handshake or ignored the request, now try again
985*de0e0e4dSAntonio Huete Jimenez 	 * to obtain the (application) data we were asked for.
986*de0e0e4dSAntonio Huete Jimenez 	 */
987*de0e0e4dSAntonio Huete Jimenez 	return 1;
988*de0e0e4dSAntonio Huete Jimenez }
989*de0e0e4dSAntonio Huete Jimenez 
99072c33676SMaxim Ag /* Return up to 'len' payload bytes received in 'type' records.
99172c33676SMaxim Ag  * 'type' is one of the following:
99272c33676SMaxim Ag  *
99372c33676SMaxim Ag  *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
99472c33676SMaxim Ag  *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
99572c33676SMaxim Ag  *   -  0 (during a shutdown, no data has to be returned)
99672c33676SMaxim Ag  *
99772c33676SMaxim Ag  * If we don't have stored data to work from, read a SSL/TLS record first
99872c33676SMaxim Ag  * (possibly multiple records if we still don't have anything to return).
99972c33676SMaxim Ag  *
100072c33676SMaxim Ag  * This function must handle any surprises the peer may have for us, such as
100172c33676SMaxim Ag  * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
100272c33676SMaxim Ag  * a surprise, but handled as if it were), or renegotiation requests.
100372c33676SMaxim Ag  * Also if record payloads contain fragments too small to process, we store
100472c33676SMaxim Ag  * them until there is enough for the respective protocol (the record protocol
100572c33676SMaxim Ag  * may use arbitrary fragmentation and even interleaving):
100672c33676SMaxim Ag  *     Change cipher spec protocol
100772c33676SMaxim Ag  *             just 1 byte needed, no need for keeping anything stored
100872c33676SMaxim Ag  *     Alert protocol
100972c33676SMaxim Ag  *             2 bytes needed (AlertLevel, AlertDescription)
101072c33676SMaxim Ag  *     Handshake protocol
101172c33676SMaxim Ag  *             4 bytes needed (HandshakeType, uint24 length) -- we just have
101272c33676SMaxim Ag  *             to detect unexpected Client Hello and Hello Request messages
101372c33676SMaxim Ag  *             here, anything else is handled by higher layers
101472c33676SMaxim Ag  *     Application data protocol
101572c33676SMaxim Ag  *             none of our business
101672c33676SMaxim Ag  */
101772c33676SMaxim Ag int
ssl3_read_bytes(SSL * s,int type,unsigned char * buf,int len,int peek)101872c33676SMaxim Ag ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
101972c33676SMaxim Ag {
1020cca6fc52SDaniel Fojt 	SSL3_RECORD_INTERNAL *rr;
1021*de0e0e4dSAntonio Huete Jimenez 	int rrcount = 0;
1022*de0e0e4dSAntonio Huete Jimenez 	unsigned int n;
1023*de0e0e4dSAntonio Huete Jimenez 	int ret;
102472c33676SMaxim Ag 
1025*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->rbuf.buf == NULL) {
102672c33676SMaxim Ag 		if (!ssl3_setup_read_buffer(s))
1027*de0e0e4dSAntonio Huete Jimenez 			return -1;
1028*de0e0e4dSAntonio Huete Jimenez 	}
102972c33676SMaxim Ag 
103072c33676SMaxim Ag 	if (len < 0) {
103172c33676SMaxim Ag 		SSLerror(s, ERR_R_INTERNAL_ERROR);
103272c33676SMaxim Ag 		return -1;
103372c33676SMaxim Ag 	}
103472c33676SMaxim Ag 
1035*de0e0e4dSAntonio Huete Jimenez 	if (type != 0 && type != SSL3_RT_APPLICATION_DATA &&
1036*de0e0e4dSAntonio Huete Jimenez 	    type != SSL3_RT_HANDSHAKE) {
1037*de0e0e4dSAntonio Huete Jimenez 		SSLerror(s, ERR_R_INTERNAL_ERROR);
1038*de0e0e4dSAntonio Huete Jimenez 		return -1;
1039*de0e0e4dSAntonio Huete Jimenez 	}
1040*de0e0e4dSAntonio Huete Jimenez 	if (peek && type != SSL3_RT_APPLICATION_DATA) {
104172c33676SMaxim Ag 		SSLerror(s, ERR_R_INTERNAL_ERROR);
104272c33676SMaxim Ag 		return -1;
104372c33676SMaxim Ag 	}
104472c33676SMaxim Ag 
1045*de0e0e4dSAntonio Huete Jimenez 	if (type == SSL3_RT_HANDSHAKE && s->s3->handshake_fragment_len > 0) {
1046*de0e0e4dSAntonio Huete Jimenez 		/* Partially satisfy request from fragment storage. */
1047*de0e0e4dSAntonio Huete Jimenez 		unsigned char *src = s->s3->handshake_fragment;
104872c33676SMaxim Ag 		unsigned char *dst = buf;
104972c33676SMaxim Ag 		unsigned int k;
105072c33676SMaxim Ag 
105172c33676SMaxim Ag 		/* peek == 0 */
105272c33676SMaxim Ag 		n = 0;
1053*de0e0e4dSAntonio Huete Jimenez 		while (len > 0 && s->s3->handshake_fragment_len > 0) {
105472c33676SMaxim Ag 			*dst++ = *src++;
105572c33676SMaxim Ag 			len--;
1056*de0e0e4dSAntonio Huete Jimenez 			s->s3->handshake_fragment_len--;
105772c33676SMaxim Ag 			n++;
105872c33676SMaxim Ag 		}
105972c33676SMaxim Ag 		/* move any remaining fragment bytes: */
1060*de0e0e4dSAntonio Huete Jimenez 		for (k = 0; k < s->s3->handshake_fragment_len; k++)
1061*de0e0e4dSAntonio Huete Jimenez 			s->s3->handshake_fragment[k] = *src++;
106272c33676SMaxim Ag 		return n;
106372c33676SMaxim Ag 	}
106472c33676SMaxim Ag 
1065*de0e0e4dSAntonio Huete Jimenez 	if (SSL_in_init(s) && !s->internal->in_handshake) {
1066*de0e0e4dSAntonio Huete Jimenez 		if ((ret = s->internal->handshake_func(s)) < 0)
1067*de0e0e4dSAntonio Huete Jimenez 			return ret;
1068*de0e0e4dSAntonio Huete Jimenez 		if (ret == 0) {
106972c33676SMaxim Ag 			SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE);
1070*de0e0e4dSAntonio Huete Jimenez 			return -1;
107172c33676SMaxim Ag 		}
107272c33676SMaxim Ag 	}
107372c33676SMaxim Ag 
107472c33676SMaxim Ag  start:
107572c33676SMaxim Ag 	/*
107672c33676SMaxim Ag 	 * Do not process more than three consecutive records, otherwise the
107772c33676SMaxim Ag 	 * peer can cause us to loop indefinitely. Instead, return with an
107872c33676SMaxim Ag 	 * SSL_ERROR_WANT_READ so the caller can choose when to handle further
107972c33676SMaxim Ag 	 * processing. In the future, the total number of non-handshake and
108072c33676SMaxim Ag 	 * non-application data records per connection should probably also be
108172c33676SMaxim Ag 	 * limited...
108272c33676SMaxim Ag 	 */
108372c33676SMaxim Ag 	if (rrcount++ >= 3) {
108472c33676SMaxim Ag 		ssl_force_want_read(s);
108572c33676SMaxim Ag 		return -1;
108672c33676SMaxim Ag 	}
108772c33676SMaxim Ag 
108872c33676SMaxim Ag 	s->internal->rwstate = SSL_NOTHING;
108972c33676SMaxim Ag 
1090*de0e0e4dSAntonio Huete Jimenez 	rr = &s->s3->rrec;
109172c33676SMaxim Ag 
1092*de0e0e4dSAntonio Huete Jimenez 	if (rr->length == 0 || s->internal->rstate == SSL_ST_READ_BODY) {
1093*de0e0e4dSAntonio Huete Jimenez 		if ((ret = ssl3_get_record(s)) <= 0)
1094*de0e0e4dSAntonio Huete Jimenez 			return ret;
109572c33676SMaxim Ag 	}
109672c33676SMaxim Ag 
1097*de0e0e4dSAntonio Huete Jimenez 	/* We now have a packet which can be read and processed. */
109872c33676SMaxim Ag 
1099*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE) {
110072c33676SMaxim Ag 		SSLerror(s, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
1101*de0e0e4dSAntonio Huete Jimenez 		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
1102*de0e0e4dSAntonio Huete Jimenez 		return -1;
110372c33676SMaxim Ag 	}
110472c33676SMaxim Ag 
1105*de0e0e4dSAntonio Huete Jimenez 	/*
1106*de0e0e4dSAntonio Huete Jimenez 	 * If the other end has shut down, throw anything we read away (even in
1107*de0e0e4dSAntonio Huete Jimenez 	 * 'peek' mode).
1108*de0e0e4dSAntonio Huete Jimenez 	 */
110972c33676SMaxim Ag 	if (s->internal->shutdown & SSL_RECEIVED_SHUTDOWN) {
111072c33676SMaxim Ag 		s->internal->rwstate = SSL_NOTHING;
1111*de0e0e4dSAntonio Huete Jimenez 		rr->length = 0;
1112*de0e0e4dSAntonio Huete Jimenez 		return 0;
111372c33676SMaxim Ag 	}
111472c33676SMaxim Ag 
111572c33676SMaxim Ag 	/* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
111672c33676SMaxim Ag 	if (type == rr->type) {
1117*de0e0e4dSAntonio Huete Jimenez 		/*
1118*de0e0e4dSAntonio Huete Jimenez 		 * Make sure that we are not getting application data when we
1119*de0e0e4dSAntonio Huete Jimenez 		 * are doing a handshake for the first time.
1120*de0e0e4dSAntonio Huete Jimenez 		 */
1121*de0e0e4dSAntonio Huete Jimenez 		if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA &&
1122*de0e0e4dSAntonio Huete Jimenez 		    !tls12_record_layer_read_protected(s->internal->rl)) {
112372c33676SMaxim Ag 			SSLerror(s, SSL_R_APP_DATA_IN_HANDSHAKE);
1124*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL,
1125*de0e0e4dSAntonio Huete Jimenez 			    SSL_AD_UNEXPECTED_MESSAGE);
1126*de0e0e4dSAntonio Huete Jimenez 			return -1;
112772c33676SMaxim Ag 		}
112872c33676SMaxim Ag 
112972c33676SMaxim Ag 		if (len <= 0)
1130*de0e0e4dSAntonio Huete Jimenez 			return len;
113172c33676SMaxim Ag 
113272c33676SMaxim Ag 		if ((unsigned int)len > rr->length)
113372c33676SMaxim Ag 			n = rr->length;
113472c33676SMaxim Ag 		else
113572c33676SMaxim Ag 			n = (unsigned int)len;
113672c33676SMaxim Ag 
1137*de0e0e4dSAntonio Huete Jimenez 		memcpy(buf, &rr->data[rr->off], n);
113872c33676SMaxim Ag 		if (!peek) {
1139*de0e0e4dSAntonio Huete Jimenez 			memset(&rr->data[rr->off], 0, n);
114072c33676SMaxim Ag 			rr->length -= n;
114172c33676SMaxim Ag 			rr->off += n;
114272c33676SMaxim Ag 			if (rr->length == 0) {
114372c33676SMaxim Ag 				s->internal->rstate = SSL_ST_READ_HEADER;
114472c33676SMaxim Ag 				rr->off = 0;
114572c33676SMaxim Ag 				if (s->internal->mode & SSL_MODE_RELEASE_BUFFERS &&
1146*de0e0e4dSAntonio Huete Jimenez 				    s->s3->rbuf.left == 0)
114772c33676SMaxim Ag 					ssl3_release_read_buffer(s);
114872c33676SMaxim Ag 			}
114972c33676SMaxim Ag 		}
1150*de0e0e4dSAntonio Huete Jimenez 
1151*de0e0e4dSAntonio Huete Jimenez 		return n;
115272c33676SMaxim Ag 	}
115372c33676SMaxim Ag 
115472c33676SMaxim Ag 	/*
1155*de0e0e4dSAntonio Huete Jimenez 	 * If we get here, then type != rr->type; if we have a handshake
1156*de0e0e4dSAntonio Huete Jimenez 	 * message, then it was unexpected (Hello Request or Client Hello).
115772c33676SMaxim Ag 	 */
115872c33676SMaxim Ag 
1159*de0e0e4dSAntonio Huete Jimenez 	if (rr->type == SSL3_RT_ALERT) {
1160*de0e0e4dSAntonio Huete Jimenez 		if ((ret = ssl3_read_alert(s)) <= 0)
1161*de0e0e4dSAntonio Huete Jimenez 			return ret;
116272c33676SMaxim Ag 		goto start;
116372c33676SMaxim Ag 	}
116472c33676SMaxim Ag 
116572c33676SMaxim Ag 	if (s->internal->shutdown & SSL_SENT_SHUTDOWN) {
116672c33676SMaxim Ag 		s->internal->rwstate = SSL_NOTHING;
116772c33676SMaxim Ag 		rr->length = 0;
1168*de0e0e4dSAntonio Huete Jimenez 		return 0;
1169*de0e0e4dSAntonio Huete Jimenez 	}
1170*de0e0e4dSAntonio Huete Jimenez 
1171*de0e0e4dSAntonio Huete Jimenez 	if (rr->type == SSL3_RT_APPLICATION_DATA) {
1172*de0e0e4dSAntonio Huete Jimenez 		/*
1173*de0e0e4dSAntonio Huete Jimenez 		 * At this point, we were expecting handshake data, but have
1174*de0e0e4dSAntonio Huete Jimenez 		 * application data. If the library was running inside
1175*de0e0e4dSAntonio Huete Jimenez 		 * ssl3_read() (i.e. in_read_app_data is set) and it makes
1176*de0e0e4dSAntonio Huete Jimenez 		 * sense to read application data at this point (session
1177*de0e0e4dSAntonio Huete Jimenez 		 * renegotiation not yet started), we will indulge it.
1178*de0e0e4dSAntonio Huete Jimenez 		 */
1179*de0e0e4dSAntonio Huete Jimenez 		if (s->s3->in_read_app_data != 0 &&
1180*de0e0e4dSAntonio Huete Jimenez 		    s->s3->total_renegotiations != 0 &&
1181*de0e0e4dSAntonio Huete Jimenez 		    (((s->s3->hs.state & SSL_ST_CONNECT) &&
1182*de0e0e4dSAntonio Huete Jimenez 		    (s->s3->hs.state >= SSL3_ST_CW_CLNT_HELLO_A) &&
1183*de0e0e4dSAntonio Huete Jimenez 		    (s->s3->hs.state <= SSL3_ST_CR_SRVR_HELLO_A)) || (
1184*de0e0e4dSAntonio Huete Jimenez 		    (s->s3->hs.state & SSL_ST_ACCEPT) &&
1185*de0e0e4dSAntonio Huete Jimenez 		    (s->s3->hs.state <= SSL3_ST_SW_HELLO_REQ_A) &&
1186*de0e0e4dSAntonio Huete Jimenez 		    (s->s3->hs.state >= SSL3_ST_SR_CLNT_HELLO_A)))) {
1187*de0e0e4dSAntonio Huete Jimenez 			s->s3->in_read_app_data = 2;
1188*de0e0e4dSAntonio Huete Jimenez 			return -1;
1189*de0e0e4dSAntonio Huete Jimenez 		} else {
1190*de0e0e4dSAntonio Huete Jimenez 			SSLerror(s, SSL_R_UNEXPECTED_RECORD);
1191*de0e0e4dSAntonio Huete Jimenez 			ssl3_send_alert(s, SSL3_AL_FATAL,
1192*de0e0e4dSAntonio Huete Jimenez 			    SSL_AD_UNEXPECTED_MESSAGE);
1193*de0e0e4dSAntonio Huete Jimenez 			return -1;
1194*de0e0e4dSAntonio Huete Jimenez 		}
119572c33676SMaxim Ag 	}
119672c33676SMaxim Ag 
119772c33676SMaxim Ag 	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
1198*de0e0e4dSAntonio Huete Jimenez 		if ((ret = ssl3_read_change_cipher_spec(s)) <= 0)
1199*de0e0e4dSAntonio Huete Jimenez 			return ret;
120072c33676SMaxim Ag 		goto start;
120172c33676SMaxim Ag 	}
120272c33676SMaxim Ag 
1203*de0e0e4dSAntonio Huete Jimenez 	if (rr->type == SSL3_RT_HANDSHAKE) {
1204*de0e0e4dSAntonio Huete Jimenez 		if ((ret = ssl3_read_handshake_unexpected(s)) <= 0)
1205*de0e0e4dSAntonio Huete Jimenez 			return ret;
120672c33676SMaxim Ag 		goto start;
120772c33676SMaxim Ag 	}
120872c33676SMaxim Ag 
120972c33676SMaxim Ag 	/*
1210*de0e0e4dSAntonio Huete Jimenez 	 * Unknown record type - TLSv1.2 sends an unexpected message alert while
1211*de0e0e4dSAntonio Huete Jimenez 	 * earlier versions silently ignore the record.
121272c33676SMaxim Ag 	 */
1213*de0e0e4dSAntonio Huete Jimenez 	if (ssl_effective_tls_version(s) <= TLS1_1_VERSION) {
121472c33676SMaxim Ag 		rr->length = 0;
121572c33676SMaxim Ag 		goto start;
121672c33676SMaxim Ag 	}
121772c33676SMaxim Ag 	SSLerror(s, SSL_R_UNEXPECTED_RECORD);
1218*de0e0e4dSAntonio Huete Jimenez 	ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
1219*de0e0e4dSAntonio Huete Jimenez 	return -1;
122072c33676SMaxim Ag }
122172c33676SMaxim Ag 
122272c33676SMaxim Ag int
ssl3_do_change_cipher_spec(SSL * s)122372c33676SMaxim Ag ssl3_do_change_cipher_spec(SSL *s)
122472c33676SMaxim Ag {
1225*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->hs.tls12.key_block == NULL) {
122672c33676SMaxim Ag 		if (s->session == NULL || s->session->master_key_length == 0) {
122772c33676SMaxim Ag 			/* might happen if dtls1_read_bytes() calls this */
122872c33676SMaxim Ag 			SSLerror(s, SSL_R_CCS_RECEIVED_EARLY);
122972c33676SMaxim Ag 			return (0);
123072c33676SMaxim Ag 		}
123172c33676SMaxim Ag 
1232*de0e0e4dSAntonio Huete Jimenez 		s->session->cipher = s->s3->hs.cipher;
123372c33676SMaxim Ag 		if (!tls1_setup_key_block(s))
123472c33676SMaxim Ag 			return (0);
123572c33676SMaxim Ag 	}
123672c33676SMaxim Ag 
1237*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_change_read_cipher_state(s))
123872c33676SMaxim Ag 		return (0);
123972c33676SMaxim Ag 
1240*de0e0e4dSAntonio Huete Jimenez 	/*
1241*de0e0e4dSAntonio Huete Jimenez 	 * We have to record the message digest at this point so we can get it
1242*de0e0e4dSAntonio Huete Jimenez 	 * before we read the finished message.
1243*de0e0e4dSAntonio Huete Jimenez 	 */
1244*de0e0e4dSAntonio Huete Jimenez 	if (!tls12_derive_peer_finished(s))
1245*de0e0e4dSAntonio Huete Jimenez 		return (0);
124672c33676SMaxim Ag 
124772c33676SMaxim Ag 	return (1);
124872c33676SMaxim Ag }
124972c33676SMaxim Ag 
1250*de0e0e4dSAntonio Huete Jimenez static int
ssl3_write_alert(SSL * s)1251*de0e0e4dSAntonio Huete Jimenez ssl3_write_alert(SSL *s)
1252*de0e0e4dSAntonio Huete Jimenez {
1253*de0e0e4dSAntonio Huete Jimenez 	if (SSL_is_dtls(s))
1254*de0e0e4dSAntonio Huete Jimenez 		return do_dtls1_write(s, SSL3_RT_ALERT, s->s3->send_alert,
1255*de0e0e4dSAntonio Huete Jimenez 		    sizeof(s->s3->send_alert));
1256*de0e0e4dSAntonio Huete Jimenez 
1257*de0e0e4dSAntonio Huete Jimenez 	return do_ssl3_write(s, SSL3_RT_ALERT, s->s3->send_alert,
1258*de0e0e4dSAntonio Huete Jimenez 	    sizeof(s->s3->send_alert));
1259*de0e0e4dSAntonio Huete Jimenez }
1260*de0e0e4dSAntonio Huete Jimenez 
126172c33676SMaxim Ag int
ssl3_send_alert(SSL * s,int level,int desc)126272c33676SMaxim Ag ssl3_send_alert(SSL *s, int level, int desc)
126372c33676SMaxim Ag {
1264*de0e0e4dSAntonio Huete Jimenez 	/* If alert is fatal, remove session from cache. */
1265*de0e0e4dSAntonio Huete Jimenez 	if (level == SSL3_AL_FATAL)
126672c33676SMaxim Ag 		SSL_CTX_remove_session(s->ctx, s->session);
126772c33676SMaxim Ag 
1268*de0e0e4dSAntonio Huete Jimenez 	s->s3->alert_dispatch = 1;
1269*de0e0e4dSAntonio Huete Jimenez 	s->s3->send_alert[0] = level;
1270*de0e0e4dSAntonio Huete Jimenez 	s->s3->send_alert[1] = desc;
127172c33676SMaxim Ag 
1272*de0e0e4dSAntonio Huete Jimenez 	/*
1273*de0e0e4dSAntonio Huete Jimenez 	 * If data is still being written out, the alert will be dispatched at
1274*de0e0e4dSAntonio Huete Jimenez 	 * some point in the future.
1275*de0e0e4dSAntonio Huete Jimenez 	 */
1276*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->wbuf.left != 0)
127772c33676SMaxim Ag 		return -1;
1278*de0e0e4dSAntonio Huete Jimenez 
1279*de0e0e4dSAntonio Huete Jimenez 	return ssl3_dispatch_alert(s);
128072c33676SMaxim Ag }
128172c33676SMaxim Ag 
128272c33676SMaxim Ag int
ssl3_dispatch_alert(SSL * s)128372c33676SMaxim Ag ssl3_dispatch_alert(SSL *s)
128472c33676SMaxim Ag {
1285*de0e0e4dSAntonio Huete Jimenez 	int ret;
128672c33676SMaxim Ag 
1287*de0e0e4dSAntonio Huete Jimenez 	s->s3->alert_dispatch = 0;
1288*de0e0e4dSAntonio Huete Jimenez 	if ((ret = ssl3_write_alert(s)) <= 0) {
1289*de0e0e4dSAntonio Huete Jimenez 		s->s3->alert_dispatch = 1;
1290*de0e0e4dSAntonio Huete Jimenez 		return ret;
1291*de0e0e4dSAntonio Huete Jimenez 	}
1292*de0e0e4dSAntonio Huete Jimenez 
1293*de0e0e4dSAntonio Huete Jimenez 	/*
1294*de0e0e4dSAntonio Huete Jimenez 	 * Alert sent to BIO.  If it is important, flush it now.
129572c33676SMaxim Ag 	 * If the message does not get sent due to non-blocking IO,
1296*de0e0e4dSAntonio Huete Jimenez 	 * we will not worry too much.
1297*de0e0e4dSAntonio Huete Jimenez 	 */
1298*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->send_alert[0] == SSL3_AL_FATAL)
129972c33676SMaxim Ag 		(void)BIO_flush(s->wbio);
130072c33676SMaxim Ag 
1301*de0e0e4dSAntonio Huete Jimenez 	ssl_msg_callback(s, 1, SSL3_RT_ALERT, s->s3->send_alert, 2);
130272c33676SMaxim Ag 
1303*de0e0e4dSAntonio Huete Jimenez 	ssl_info_callback(s, SSL_CB_WRITE_ALERT,
1304*de0e0e4dSAntonio Huete Jimenez 	    (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]);
130572c33676SMaxim Ag 
1306*de0e0e4dSAntonio Huete Jimenez 	return ret;
130772c33676SMaxim Ag }
1308