195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved.
395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written
595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com).
695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL.
795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as
995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to.  The following conditions
1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA,
1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms
1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in
1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed.
1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution
1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used.
1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or
2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package.
2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without
2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions
2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met:
2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright
2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer.
2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright
2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer in the
2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    documentation and/or other materials provided with the distribution.
3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software
3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    must display the following acknowledgement:
3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes cryptographic software written by
3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *     Eric Young (eay@cryptsoft.com)"
3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    The word 'cryptographic' can be left out if the rouines from the library
3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    being used are not cryptographic related :-).
3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from
3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    the apps directory (application code) you must include an acknowledgement:
3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE.
5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or
5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed.  i.e. this code cannot simply be
5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence
5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.]
5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* ====================================================================
5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without
6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions
6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met:
6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the above copyright
6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer.
6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright
6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer in
6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    the documentation and/or other materials provided with the
7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    distribution.
7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this
7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    software must display the following acknowledgment:
7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software developed by the OpenSSL Project
7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    endorse or promote products derived from this software without
7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    prior written permission. For written permission, please contact
8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    openssl-core@openssl.org.
8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5. Products derived from this software may not be called "OpenSSL"
8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    nor may "OpenSSL" appear in their names without prior written
8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    permission of the OpenSSL Project.
8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6. Redistributions of any form whatsoever must retain the following
8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    acknowledgment:
8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software developed by the OpenSSL Project
8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF THE POSSIBILITY OF SUCH DAMAGE.
10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ====================================================================
10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This product includes cryptographic software written by Eric Young
10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (eay@cryptsoft.com).  This product includes software written by Tim
10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Hudson (tjh@cryptsoft.com). */
10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <assert.h>
11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <errno.h>
11187750b433a5d2d252ee5bd879cae553c046fd0e7Adam Langley#include <limits.h>
11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <stdio.h>
11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/buf.h>
11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h>
11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/evp.h>
11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h>
11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/rand.h>
11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "ssl_locl.h"
12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
123d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			 unsigned int len, char fragment, char is_fragment);
12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int ssl3_get_record(SSL *s);
12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ssl3_read_n(SSL *s, int n, int max, int extend)
12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* If extend == 0, obtain new n-byte packet; if extend == 1, increase
12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * packet by another n bytes.
13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * The packet will be in the sub-array of s->s3->rbuf.buf specified
13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * by s->packet and s->packet_length.
13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * (If s->read_ahead is set, 'max' bytes may be stored in rbuf
13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * [plus s->packet_length bytes if extend == 1].)
13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 */
13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i,len,left;
13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	long align=0;
13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	unsigned char *pkt;
13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	SSL3_BUFFER *rb;
13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (n <= 0) return n;
14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rb    = &(s->s3->rbuf);
14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (rb->buf == NULL)
14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!ssl3_setup_read_buffer(s))
14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return -1;
14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	left  = rb->left;
14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	align = (long)rb->buf + SSL3_RT_HEADER_LENGTH;
15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!extend)
15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* start with empty packet ... */
15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (left == 0)
15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			rb->offset = align;
15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH)
15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			/* check if next packet length is large
16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * enough to justify payload alignment... */
16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			pkt = rb->buf + rb->offset;
16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (pkt[0] == SSL3_RT_APPLICATION_DATA
16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			    && (pkt[3]<<8|pkt[4]) >= 128)
16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				/* Note that even if packet is corrupted
16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * and its length field is insane, we can
16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * only be led to wrong decision about
16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * whether memmove will occur or not.
17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * Header values has no effect on memmove
17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * arguments and therefore no buffer
17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * overrun can be triggered. */
17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				memmove (rb->buf+align,pkt,left);
17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				rb->offset = align;
17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->packet = rb->buf + rb->offset;
17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->packet_length = 0;
17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* ... now we can act as if 'extend' was set */
18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* For DTLS/UDP reads should not span multiple packets
18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * because the read operation returns the whole packet
18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * at once (as long as it fits into the buffer). */
18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (SSL_IS_DTLS(s))
18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (left > 0 && n > left)
18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			n = left;
18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* if there is enough in the buffer from a previous read, take some */
19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (left >= n)
19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->packet_length+=n;
19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rb->left=left-n;
19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rb->offset+=n;
19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return(n);
19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* else we need to read more data */
20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	len = s->packet_length;
20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	pkt = rb->buf+align;
20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Move any available bytes to front of buffer:
20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * 'len' bytes already pointed to by 'packet',
20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * 'left' extra ones at the end */
20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->packet != pkt) /* len > 0 */
20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		memmove(pkt, s->packet, len+left);
21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->packet = pkt;
21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rb->offset = len + align;
21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (n > (int)(rb->len - rb->offset)) /* does not happen */
21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_read_n, ERR_R_INTERNAL_ERROR);
21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return -1;
21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!s->read_ahead)
22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* ignore max parameter */
22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		max = n;
22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (max < n)
22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			max = n;
22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (max > (int)(rb->len - rb->offset))
22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			max = rb->len - rb->offset;
22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	while (left < n)
23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* Now we have len+left bytes at the front of s->s3->rbuf.buf
23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * and need to read in more until we have len+n (up to
23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * len+max if possible) */
23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ERR_clear_system_error();
23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->rbio != NULL)
23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->rwstate=SSL_READING;
24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			i=BIO_read(s->rbio,pkt+len+left, max-left);
24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_n, SSL_R_READ_BIO_NOT_SET);
24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			i = -1;
24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i <= 0)
25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			rb->left = left;
25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				!SSL_IS_DTLS(s))
25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				if (len+left == 0)
25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					ssl3_release_read_buffer(s);
25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(i);
25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		left+=i;
25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* reads should *never* span multiple packets for DTLS because
26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * the underlying transport protocol is message oriented as opposed
26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * to byte oriented as in the TLS case. */
26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (SSL_IS_DTLS(s))
26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (n > left)
26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				n = left; /* makes the while condition false */
26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* done reading, now the book-keeping */
27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rb->offset += n;
27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rb->left = left - n;
27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->packet_length += n;
27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->rwstate=SSL_NOTHING;
27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return(n);
27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
27748105fa2152b82b6d918c12587d00e86438437bdAdam Langley/* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that will
27848105fa2152b82b6d918c12587d00e86438437bdAdam Langley * be processed per call to ssl3_get_record. Without this limit an attacker
27948105fa2152b82b6d918c12587d00e86438437bdAdam Langley * could send empty records at a faster rate than we can process and cause
28048105fa2152b82b6d918c12587d00e86438437bdAdam Langley * ssl3_get_record to loop forever. */
28148105fa2152b82b6d918c12587d00e86438437bdAdam Langley#define MAX_EMPTY_RECORDS 32
28248105fa2152b82b6d918c12587d00e86438437bdAdam Langley
28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Call this to get a new input record.
28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * It will return <= 0 if more data is needed, normally due to an error
28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * or non-blocking IO.
28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * When it finishes, one packet has been decoded and can be found in
28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ssl->s3->rrec.type    - is the type of record
28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ssl->s3->rrec.data, 	 - data
28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ssl->s3->rrec.length, - number of bytes
29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* used only by ssl3_read_bytes */
29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int ssl3_get_record(SSL *s)
29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int ssl_major,ssl_minor,al;
29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int enc_err,n,i,ret= -1;
29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	SSL3_RECORD *rr;
29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	SSL_SESSION *sess;
29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	unsigned char *p;
29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	unsigned char md[EVP_MAX_MD_SIZE];
30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	short version;
30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	unsigned mac_size, orig_len;
30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t extra;
30348105fa2152b82b6d918c12587d00e86438437bdAdam Langley	unsigned empty_record_count = 0;
30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rr= &(s->s3->rrec);
30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sess=s->session;
30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		extra=SSL3_RT_MAX_EXTRA;
31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		extra=0;
31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (extra && !s->s3->init_extra)
31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
314c92c2d7a076ca61d61f3c96b837b18bfdfb56cb5David Benjamin		/* An application error: SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * set after ssl3_setup_buffers() was done */
31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_get_record, ERR_R_INTERNAL_ERROR);
31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return -1;
31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyagain:
32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* check if we have the header */
32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (	(s->rstate != SSL_ST_READ_BODY) ||
32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->packet_length < SSL3_RT_HEADER_LENGTH))
32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (n <= 0) return(n); /* error or non-blocking */
32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->rstate=SSL_ST_READ_BODY;
32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		p=s->packet;
33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->msg_callback)
33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, s->msg_callback_arg);
33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* Pull apart the header into the SSL3_RECORD */
33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rr->type= *(p++);
33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ssl_major= *(p++);
33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ssl_minor= *(p++);
33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		version=(ssl_major<<8)|ssl_minor;
33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		n2s(p,rr->length);
33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if 0
34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyfprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* Lets check version */
34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!s->first_packet)
34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (version != s->version)
34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_WRONG_VERSION_NUMBER);
34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                                if ((s->version & 0xFF00) == (version & 0xFF00) && !s->enc_write_ctx && !s->write_hash)
35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                                	/* Send back error using their minor version number :-) */
35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					s->version = (unsigned short)version;
35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				al=SSL_AD_PROTOCOL_VERSION;
35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto f_err;
35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if ((version>>8) != SSL3_VERSION_MAJOR)
35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_WRONG_VERSION_NUMBER);
36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			al=SSL_AD_RECORD_OVERFLOW;
36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_PACKET_LENGTH_TOO_LONG);
36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto f_err;
36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* now s->rstate == SSL_ST_READ_BODY */
37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */
37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (rr->length > s->packet_length-SSL3_RT_HEADER_LENGTH)
37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* now s->packet_length == SSL3_RT_HEADER_LENGTH */
37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		i=rr->length;
37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		n=ssl3_read_n(s,i,i,1);
38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (n <= 0) return(n); /* error or non-blocking io */
38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* now n == rr->length,
38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * and s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length */
38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * and we have that many bytes in s->packet
38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 */
39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]);
39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* ok, we can now read from 's->packet' data into 'rr'
39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * rr->input points at rr->length bytes, which
39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * need to be copied into rr->data by either
39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * the decryption or by the decompression
39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * When the data is 'copied' into the rr->data buffer,
39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * rr->input will be pointed at the new buffer */
39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * rr->length bytes of encrypted compressed stuff. */
40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* check is not needed I believe */
40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		al=SSL_AD_RECORD_OVERFLOW;
40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto f_err;
40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* decrypt in place in 'rr->input' */
41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rr->data=rr->input;
41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	enc_err = s->method->ssl3_enc->enc(s,0);
41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* enc_err is:
41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 *    0: (in non-constant time) if the record is publically invalid.
41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 *    1: if the padding is valid
41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 *    -1: if the padding is invalid */
41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (enc_err == 0)
41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		al=SSL_AD_DECRYPTION_FAILED;
42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto f_err;
42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#ifdef TLS_DEBUG
42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyprintf("dec %d\n",rr->length);
42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyprintf("\n");
42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* r->length is now the compressed data plus mac */
43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((sess != NULL) &&
43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	    (s->enc_read_ctx != NULL) &&
43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	    (EVP_MD_CTX_md(s->read_hash) != NULL))
43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* s->read_hash != NULL => mac_size != -1 */
43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		unsigned char *mac = NULL;
43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		unsigned char mac_tmp[EVP_MAX_MD_SIZE];
43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		mac_size=EVP_MD_CTX_size(s->read_hash);
44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		assert(mac_size <= EVP_MAX_MD_SIZE);
44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* kludge: *_cbc_remove_padding passes padding length in rr->type */
44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		orig_len = rr->length+((unsigned int)rr->type>>8);
44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* orig_len is the length of the record before any padding was
44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * removed. This is public information, as is the MAC in use,
44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * therefore we can safely process the record in a different
44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * amount of time if it's too short to possibly contain a MAC.
44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 */
45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (orig_len < mac_size ||
45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		    /* CBC records must have a padding length byte too. */
45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		    (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		     orig_len < mac_size+1))
45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			al=SSL_AD_DECODE_ERROR;
45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_LENGTH_TOO_SHORT);
45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto f_err;
45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			/* We update the length so that the TLS header bytes
46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * can be constructed correctly but we need to extract
46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * the MAC in constant time from within the record,
46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * without leaking the contents of the padding bytes.
46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * */
46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			mac = mac_tmp;
46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			rr->length -= mac_size;
47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			/* In this case there's no padding, so |orig_len|
47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * equals |rec->length| and we checked that there's
47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * enough bytes for |mac_size| above. */
47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			rr->length -= mac_size;
47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			mac = &rr->data[rr->length];
47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			enc_err = -1;
48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			enc_err = -1;
48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (enc_err < 0)
48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* A separate 'decryption_failed' alert was introduced with TLS 1.0,
49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
49195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * failure is directly visible from the ciphertext anyway,
49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * we should not reveal which kind of error occured -- this
49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * might become visible to an attacker (e.g. via a logfile) */
49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		al=SSL_AD_BAD_RECORD_MAC;
49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto f_err;
49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra)
50095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		al=SSL_AD_RECORD_OVERFLOW;
50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_DATA_LENGTH_TOO_LONG);
50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto f_err;
50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
50695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rr->off=0;
50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* So at this point the following is true
50895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * ssl->s3->rrec.type 	is the type of record
50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * ssl->s3->rrec.length	== number of bytes in record
51095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * ssl->s3->rrec.off	== offset to first valid byte
51195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * ssl->s3->rrec.data	== where to take bytes from, increment
51295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 *			   after use :-).
51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 */
51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* we have pulled in a full packet so zero things */
51695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->packet_length=0;
51795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
51895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* just read a 0 length packet */
51948105fa2152b82b6d918c12587d00e86438437bdAdam Langley	if (rr->length == 0)
52048105fa2152b82b6d918c12587d00e86438437bdAdam Langley		{
52148105fa2152b82b6d918c12587d00e86438437bdAdam Langley		empty_record_count++;
52248105fa2152b82b6d918c12587d00e86438437bdAdam Langley		if (empty_record_count > MAX_EMPTY_RECORDS)
52348105fa2152b82b6d918c12587d00e86438437bdAdam Langley			{
52448105fa2152b82b6d918c12587d00e86438437bdAdam Langley			al=SSL_AD_UNEXPECTED_MESSAGE;
52548105fa2152b82b6d918c12587d00e86438437bdAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
52648105fa2152b82b6d918c12587d00e86438437bdAdam Langley			goto f_err;
52748105fa2152b82b6d918c12587d00e86438437bdAdam Langley			}
52848105fa2152b82b6d918c12587d00e86438437bdAdam Langley		goto again;
52948105fa2152b82b6d918c12587d00e86438437bdAdam Langley		}
53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if 0
53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyfprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
53595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return(1);
53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyf_err:
53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ssl3_send_alert(s,SSL3_AL_FATAL,al);
53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr:
54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return(ret);
54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Call this to write data in records of type 'type'
54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * It will return <= 0 if not all data has been sent or non-blocking IO.
54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
54895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	const unsigned char *buf=buf_;
54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	unsigned int tot,n,nw;
55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i;
55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->rwstate=SSL_NOTHING;
55387750b433a5d2d252ee5bd879cae553c046fd0e7Adam Langley	assert(s->s3->wnum <= INT_MAX);
55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	tot=s->s3->wnum;
55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->wnum=0;
55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (SSL_in_init(s) && !s->in_handshake)
55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		i=s->handshake_func(s);
56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i < 0) return(i);
56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i == 0)
56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_write_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return -1;
56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5689611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	/* ensure that if we end up with a smaller value of data to write
5699611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	 * out than the the original len from a write which didn't complete
5709611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	 * for non-blocking I/O and also somehow ended up avoiding
5719611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	 * the check for this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as
5729611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	 * it must never be possible to end up with (len-tot) as a large
5739611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	 * number that will then promptly send beyond the end of the users
5749611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	 * buffer ... so we trap and report the error in a way the user
5759611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	 * will notice
5769611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley	 */
57787750b433a5d2d252ee5bd879cae553c046fd0e7Adam Langley	if (len < tot)
5789611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley		{
5799611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_write_bytes, SSL_R_BAD_LENGTH);
5809611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley		return(-1);
5819611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley		}
5829611cfcb9fcf120a6c70fd6b23b296f8ca20279fAdam Langley
58395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	n=(len-tot);
58495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (;;)
58595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
586d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		/* max contains the maximum number of bytes that we can put
587d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		 * into a record. */
588d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		unsigned max = s->max_send_fragment;
589d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		/* fragment is true if do_ssl3_write should send the first byte
590d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		 * in its own record in order to randomise a CBC IV. */
591d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		int fragment = 0;
592d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley
593d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		if (n > 1 &&
594d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		    s->s3->need_record_splitting &&
595d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		    type == SSL3_RT_APPLICATION_DATA &&
596d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		    !s->s3->record_split_done)
597d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			{
598d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			fragment = 1;
599d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			/* record_split_done records that the splitting has
600d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			 * been done in case we hit an SSL_WANT_WRITE condition.
601d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			 * In that case, we don't need to do the split again. */
602d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			s->s3->record_split_done = 1;
603d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			}
604d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley
605d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		if (n > max)
606d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			nw=max;
60795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
60895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			nw=n;
60995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
610d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		i=do_ssl3_write(s, type, &(buf[tot]), nw, fragment, 0);
61195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i <= 0)
61295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
61395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->s3->wnum=tot;
6147fdeaf11017b82368e0a97547fc491b90ad40f67Kenny Root			s->s3->record_split_done = 0;
61595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return i;
61695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
61795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
61895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if ((i == (int)n) ||
61995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			(type == SSL3_RT_APPLICATION_DATA &&
62095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))
62195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
622d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			/* next chunk of data should get another prepended,
623d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			 * one-byte fragment in ciphersuites with known-IV
624d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			 * weakness. */
625d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			s->s3->record_split_done = 0;
62695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return tot+i;
62795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
62895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
62995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		n-=i;
63095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		tot+=i;
63195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
63295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
63395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
634d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley/* do_ssl3_write writes an SSL record of the given type. If |fragment| is 1
635d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley * then it splits the record into a one byte record and a record with the rest
636d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley * of the data in order to randomise a CBC IV. If |is_fragment| is true then
637d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley * this call resulted from do_ssl3_write calling itself in order to create that
638d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley * one byte fragment. */
63995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
640d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			 unsigned int len, char fragment, char is_fragment)
64195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
64295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	unsigned char *p,*plen;
643d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	int i,mac_size;
64495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int prefix_len=0;
64595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int eivlen;
64695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	long align=0;
64795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	SSL3_RECORD *wr;
64895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	SSL3_BUFFER *wb=&(s->s3->wbuf);
64995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	SSL_SESSION *sess;
65095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
65195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* first check if there is a SSL3_BUFFER still being written
65295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * out.  This will happen with non blocking IO */
65395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (wb->left != 0)
65495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return(ssl3_write_pending(s,type,buf,len));
65595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
65695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* If we have an alert to send, lets send it */
65795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->s3->alert_dispatch)
65895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
65995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		i=s->method->ssl_dispatch_alert(s);
66095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i <= 0)
66195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(i);
66295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* if it went, fall through and send more stuff */
66395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
66495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
665c6c8ae8fae1c55db07d6b6f084f3e7d31c770cb7Adam Langley	if (wb->buf == NULL)
666c6c8ae8fae1c55db07d6b6f084f3e7d31c770cb7Adam Langley		if (!ssl3_setup_write_buffer(s))
667c6c8ae8fae1c55db07d6b6f084f3e7d31c770cb7Adam Langley			return -1;
668c6c8ae8fae1c55db07d6b6f084f3e7d31c770cb7Adam Langley
669d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	if (len == 0)
67095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
67195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
67295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	wr= &(s->s3->wrec);
67395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sess=s->session;
67495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
67595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (	(sess == NULL) ||
67695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->enc_write_ctx == NULL) ||
67795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(EVP_MD_CTX_md(s->write_hash) == NULL))
67895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
67995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		mac_size=0;
68095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
68195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
68295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
68395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		mac_size=EVP_MD_CTX_size(s->write_hash);
68495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (mac_size < 0)
68595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
68695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
68795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
688d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	if (fragment)
68995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
69095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* countermeasure against known-IV weakness in CBC ciphersuites
69195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
692d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		prefix_len = do_ssl3_write(s, type, buf, 1 /* length */,
693d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley					   0 /* fragment */,
694d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley					   1 /* is_fragment */);
695d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		if (prefix_len <= 0)
696d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			goto err;
69795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
698d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		if (prefix_len > (SSL3_RT_HEADER_LENGTH +
699d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley				  SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
70095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
701d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			/* insufficient space */
702d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			OPENSSL_PUT_ERROR(SSL, do_ssl3_write, ERR_R_INTERNAL_ERROR);
703d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley			goto err;
70495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
70595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
70695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
707d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	if (is_fragment)
70895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
70995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
710d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		/* The extra fragment would be couple of cipher blocks, and
711d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		 * that will be a multiple of SSL3_ALIGN_PAYLOAD. So, if we
712d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		 * want to align the real payload, we can just pretend that we
713d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		 * have two headers and a byte. */
714d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH + 1;
71595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
71695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
71795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		p = wb->buf + align;
71895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		wb->offset  = align;
71995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
72095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else if (prefix_len)
72195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
72295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		p = wb->buf + wb->offset + prefix_len;
72395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
72495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
72595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
72695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
72795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		align = (long)wb->buf + SSL3_RT_HEADER_LENGTH;
72895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
72995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
73095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		p = wb->buf + align;
73195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		wb->offset  = align;
73295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
73395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
73495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* write the header */
73595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
73695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	*(p++)=type&0xff;
73795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	wr->type=type;
73895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
73995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	*(p++)=(s->version>>8);
74095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Some servers hang if iniatial client hello is larger than 256
74195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * bytes and record version number > TLS 1.0
74295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 */
74395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->state == SSL3_ST_CW_CLNT_HELLO_B
74495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				&& !s->renegotiate
74595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				&& TLS1_get_version(s) > TLS1_VERSION)
74695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		*(p++) = 0x1;
74795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
74895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		*(p++)=s->version&0xff;
74995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
75095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* field where we are to write out packet length */
751d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	plen=p;
75295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	p+=2;
75395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Explicit IV length, block ciphers appropriate version flag */
75495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s))
75595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
75695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
75795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (mode == EVP_CIPH_CBC_MODE)
75895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
75995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
76095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (eivlen <= 1)
76195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				eivlen = 0;
76295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
76395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
76495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			eivlen = 0;
76595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
766de0b2026841c34193cacf5c97646b38439e13200Adam Langley	else if (s->aead_write_ctx != NULL &&
767de0b2026841c34193cacf5c97646b38439e13200Adam Langley		 s->aead_write_ctx->variable_nonce_included_in_record)
768de0b2026841c34193cacf5c97646b38439e13200Adam Langley		{
769c9fb37504f1c48e37578ee7033f35e3bd236cf67Adam Langley		eivlen = s->aead_write_ctx->variable_nonce_len;
770de0b2026841c34193cacf5c97646b38439e13200Adam Langley		}
771c9fb37504f1c48e37578ee7033f35e3bd236cf67Adam Langley	else
77295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		eivlen = 0;
77395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
77495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* lets setup the record stuff. */
77595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	wr->data=p + eivlen;
776d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	wr->length=(int)(len - (fragment != 0));
777d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	wr->input=(unsigned char *)buf + (fragment != 0);
77895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
77995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* we now 'read' from wr->input, wr->length bytes into
78095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * wr->data */
78195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
7823f6fa3db62c781768b567c6f02814c0d6d27fe7fDavid Benjamin        memcpy(wr->data,wr->input,wr->length);
7833f6fa3db62c781768b567c6f02814c0d6d27fe7fDavid Benjamin        wr->input=wr->data;
78495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
78595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* we should still have the output to wr->data and the input
78695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * from wr->input.  Length should be wr->length.
78795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * wr->data still points in the wb->buf */
78895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
78995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (mac_size != 0)
79095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
79195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->method->ssl3_enc->mac(s,&(p[wr->length + eivlen]),1) < 0)
79295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
79395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		wr->length+=mac_size;
79495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
79595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
79695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	wr->input=p;
79795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	wr->data=p;
79895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
79995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (eivlen)
80095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
80195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/*	if (RAND_pseudo_bytes(p, eivlen) <= 0)
80295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err; */
80395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		wr->length += eivlen;
80495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
80595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
80695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* ssl3_enc can only have an error on read */
80795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->method->ssl3_enc->enc(s,1);
80895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
80995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* record length after mac and block padding */
81095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s2n(wr->length,plen);
81195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
81295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->msg_callback)
81395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->msg_callback(1, 0, SSL3_RT_HEADER, plen - 5, 5, s, s->msg_callback_arg);
81495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
81595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* we should now have
81695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * wr->data pointing to the encrypted data, which is
81795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * wr->length long */
81895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	wr->type=type; /* not needed but helps for debugging */
81995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	wr->length+=SSL3_RT_HEADER_LENGTH;
82095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
821d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	if (is_fragment)
82295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
823d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		/* we are in a recursive call; just return the length, don't
824d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley		 * write out anything. */
82595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return wr->length;
82695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
82795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
82895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* now let's set up wb */
82995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	wb->left = prefix_len + wr->length;
83095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
83195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* memorize arguments so that ssl3_write_pending can detect bad write retries later */
83295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->wpend_tot=len;
83395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->wpend_buf=buf;
83495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->wpend_type=type;
83595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->wpend_ret=len;
83695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
83795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* we now just need to write the buffer */
83895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ssl3_write_pending(s,type,buf,len);
83995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr:
84095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return -1;
84195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
84295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
84395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* if s->s3->wbuf.left != 0, we need to call this */
84495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
84595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	unsigned int len)
84695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
84795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i;
84895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	SSL3_BUFFER *wb=&(s->s3->wbuf);
84995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
85095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* XXXX */
85195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((s->s3->wpend_tot > (int)len)
85295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		|| ((s->s3->wpend_buf != buf) &&
85395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
85495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		|| (s->s3->wpend_type != type))
85595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
85695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_write_pending, SSL_R_BAD_WRITE_RETRY);
85795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return(-1);
85895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
85995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
86095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (;;)
86195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
86295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ERR_clear_system_error();
86395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->wbio != NULL)
86495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
86595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->rwstate=SSL_WRITING;
86695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			i=BIO_write(s->wbio,
86795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				(char *)&(wb->buf[wb->offset]),
86895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				(unsigned int)wb->left);
86995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
87095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
87195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
87295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_write_pending, SSL_R_BIO_NOT_SET);
87395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			i= -1;
87495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
87595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i == wb->left)
87695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
87795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			wb->left=0;
87895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			wb->offset+=i;
87995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
88095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				!SSL_IS_DTLS(s))
88195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				ssl3_release_write_buffer(s);
88295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->rwstate=SSL_NOTHING;
88395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(s->s3->wpend_ret);
88495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
88595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (i <= 0) {
88609bd58d1f1c71ed7ea687d0295e23793ad3d98faDavid Benjamin			if (SSL_IS_DTLS(s)) {
88795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				/* For DTLS, just drop it. That's kind of the whole
88895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				   point in using a datagram service */
88995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				wb->left = 0;
89095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
89195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(i);
89295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
89395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		wb->offset+=i;
89495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		wb->left-=i;
89595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
89695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
89795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
89886271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin/* ssl3_expect_change_cipher_spec informs the record layer that a
89986271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin * ChangeCipherSpec record is required at this point. If a Handshake record is
90086271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin * received before ChangeCipherSpec, the connection will fail. Moreover, if
90186271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin * there are unprocessed handshake bytes, the handshake will also fail and the
90286271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin * function returns zero. Otherwise, the function returns one. */
90386271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjaminint ssl3_expect_change_cipher_spec(SSL *s)
90486271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin	{
90586271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin	if (s->s3->handshake_fragment_len > 0 || s->s3->tmp.reuse_message)
90686271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		{
90786271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		OPENSSL_PUT_ERROR(SSL, ssl3_expect_change_cipher_spec, SSL_R_UNPROCESSED_HANDSHAKE_DATA);
90886271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		return 0;
90986271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		}
91086271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin	s->s3->flags |= SSL3_FLAGS_EXPECT_CCS;
91186271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin	return 1;
91286271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin	}
91386271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin
91495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Return up to 'len' payload bytes received in 'type' records.
91595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 'type' is one of the following:
91695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
91795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
91895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
91995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *   -  0 (during a shutdown, no data has to be returned)
92095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
92195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If we don't have stored data to work from, read a SSL/TLS record first
92295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (possibly multiple records if we still don't have anything to return).
92395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
92495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This function must handle any surprises the peer may have for us, such as
92595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
92695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * a surprise, but handled as if it were), or renegotiation requests.
92795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Also if record payloads contain fragments too small to process, we store
92895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * them until there is enough for the respective protocol (the record protocol
92995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * may use arbitrary fragmentation and even interleaving):
93095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *     Change cipher spec protocol
93195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *             just 1 byte needed, no need for keeping anything stored
93295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *     Alert protocol
93395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *             2 bytes needed (AlertLevel, AlertDescription)
93495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *     Handshake protocol
93595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *             4 bytes needed (HandshakeType, uint24 length) -- we just have
93695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *             to detect unexpected Client Hello and Hello Request messages
93795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *             here, anything else is handled by higher layers
93895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *     Application data protocol
93995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *             none of our business
94095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
94195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
94295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
94395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int al,i,j,ret;
94495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	unsigned int n;
94595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	SSL3_RECORD *rr;
94695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	void (*cb)(const SSL *ssl,int type2,int val)=NULL;
94795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
94895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
94995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!ssl3_setup_read_buffer(s))
95095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(-1);
95195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
95246cfb0e4ee097033c8dc20cea59cb9aef8e2e149Adam Langley	if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE)) ||
95395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	    (peek && (type != SSL3_RT_APPLICATION_DATA)))
95495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
95595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, ERR_R_INTERNAL_ERROR);
95695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return -1;
95795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
95895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
95995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0))
96095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* (partially) satisfy request from storage */
96195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
96295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		unsigned char *src = s->s3->handshake_fragment;
96395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		unsigned char *dst = buf;
96495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		unsigned int k;
96595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
96695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* peek == 0 */
96795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		n = 0;
96895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		while ((len > 0) && (s->s3->handshake_fragment_len > 0))
96995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
97095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			*dst++ = *src++;
97195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			len--; s->s3->handshake_fragment_len--;
97295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			n++;
97395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
97495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* move any remaining fragment bytes: */
97595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		for (k = 0; k < s->s3->handshake_fragment_len; k++)
97695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->s3->handshake_fragment[k] = *src++;
97795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return n;
97895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
97995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
98095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
98195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
98295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!s->in_handshake && SSL_in_init(s))
98395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
98495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* type == SSL3_RT_APPLICATION_DATA */
98595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		i=s->handshake_func(s);
98695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i < 0) return(i);
98795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i == 0)
98895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
98995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
99095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(-1);
99195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
99295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
99395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystart:
99495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->rwstate=SSL_NOTHING;
99595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
99695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* s->s3->rrec.type	    - is the type of record
99795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * s->s3->rrec.data,    - data
99895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * s->s3->rrec.off,     - offset into 'data' for next read
99995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * s->s3->rrec.length,  - number of bytes. */
100095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rr = &(s->s3->rrec);
100195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
100295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* get new packet if necessary */
100395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
100495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
100595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ret=ssl3_get_record(s);
100695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (ret <= 0) return(ret);
100795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
100895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
100995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* we now have a packet which can be read and processed */
101095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
101195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
101295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	                               * reset by ssl3_get_finished */
101395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		&& (rr->type != SSL3_RT_HANDSHAKE))
101495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
101595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		al=SSL_AD_UNEXPECTED_MESSAGE;
101695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
101795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto f_err;
101895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
101995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
102086271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin	/* If we are expecting a ChangeCipherSpec, it is illegal to receive a
102186271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin	 * Handshake record. */
102286271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin	if (rr->type == SSL3_RT_HANDSHAKE && (s->s3->flags & SSL3_FLAGS_EXPECT_CCS))
102386271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		{
102486271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		al = SSL_AD_UNEXPECTED_MESSAGE;
102586271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_HANDSHAKE_RECORD_BEFORE_CCS);
102686271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		goto f_err;
102786271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		}
102886271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin
102995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* If the other end has shut down, throw anything we read away
103095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * (even in 'peek' mode) */
103195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
103295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
103395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rr->length=0;
103495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->rwstate=SSL_NOTHING;
103595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return(0);
103695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
103795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
103895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
103995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
104095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* make sure that we are not getting application data when we
104195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * are doing a handshake for the first time */
104295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
104395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			(s->enc_read_ctx == NULL))
104495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
104595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			al=SSL_AD_UNEXPECTED_MESSAGE;
104695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE);
104795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto f_err;
104895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
104995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
105095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (len <= 0) return(len);
105195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
105295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if ((unsigned int)len > rr->length)
105395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			n = rr->length;
105495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
105595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			n = (unsigned int)len;
105695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
105795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		memcpy(buf,&(rr->data[rr->off]),n);
105895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!peek)
105995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
106095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			rr->length-=n;
106195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			rr->off+=n;
106295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (rr->length == 0)
106395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
106495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				s->rstate=SSL_ST_READ_HEADER;
106595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				rr->off=0;
10664a35a93a1238198e78bea3aeba933a57987b2187Adam Langley				if (s->mode & SSL_MODE_RELEASE_BUFFERS && s->s3->rbuf.left == 0)
106795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					ssl3_release_read_buffer(s);
106895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
106995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
107095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return(n);
107195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
107295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
107395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
107495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* If we get here, then type != rr->type; if we have a handshake
107595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * message, then it was unexpected (Hello Request or Client Hello). */
107695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
107795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* In case of record types for which we have 'fragment' storage,
107895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * fill that so that we can process the data at a fixed place.
107995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 */
108095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
108195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		unsigned int dest_maxlen = 0;
108295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		unsigned char *dest = NULL;
108395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		unsigned int *dest_len = NULL;
108495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
108595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (rr->type == SSL3_RT_HANDSHAKE)
108695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
108795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			dest_maxlen = sizeof s->s3->handshake_fragment;
108895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			dest = s->s3->handshake_fragment;
108995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			dest_len = &s->s3->handshake_fragment_len;
109095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
109195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (rr->type == SSL3_RT_ALERT)
109295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
109395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			dest_maxlen = sizeof s->s3->alert_fragment;
109495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			dest = s->s3->alert_fragment;
109595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			dest_len = &s->s3->alert_fragment_len;
109695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
109795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
109895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (dest_maxlen > 0)
109995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
110095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			n = dest_maxlen - *dest_len; /* available space in 'dest' */
110195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (rr->length < n)
110295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				n = rr->length; /* available bytes */
110395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
110495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			/* now move 'n' bytes: */
110595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			while (n-- > 0)
110695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
110795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				dest[(*dest_len)++] = rr->data[rr->off++];
110895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				rr->length--;
110995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
111095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
111195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (*dest_len < dest_maxlen)
111295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto start; /* fragment was too small */
111395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
111495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
111595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
111695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* s->s3->handshake_fragment_len == 4  iff  rr->type == SSL3_RT_HANDSHAKE;
111795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * s->s3->alert_fragment_len == 2      iff  rr->type == SSL3_RT_ALERT.
111895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
111995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
112095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* If we are a client, check for an incoming 'Hello Request': */
112195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((!s->server) &&
112295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->s3->handshake_fragment_len >= 4) &&
112395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
112495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->session != NULL) && (s->session->cipher != NULL))
112595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
112695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->s3->handshake_fragment_len = 0;
112795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
112895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if ((s->s3->handshake_fragment[1] != 0) ||
112995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			(s->s3->handshake_fragment[2] != 0) ||
113095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			(s->s3->handshake_fragment[3] != 0))
113195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
113295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			al=SSL_AD_DECODE_ERROR;
113395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_BAD_HELLO_REQUEST);
113495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto f_err;
113595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
113695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
113795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->msg_callback)
113895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg);
113995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
114095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (SSL_is_init_finished(s) &&
114195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
114295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			!s->s3->renegotiate)
114395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
114495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			ssl3_renegotiate(s);
114595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (ssl3_renegotiate_check(s))
114695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
114795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				i=s->handshake_func(s);
114895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				if (i < 0) return(i);
114995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				if (i == 0)
115095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					{
115195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
115295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					return(-1);
115395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					}
115495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
115595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				if (!(s->mode & SSL_MODE_AUTO_RETRY))
115695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					{
115795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					if (s->s3->rbuf.left == 0) /* no read-ahead left? */
115895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						{
115995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						BIO *bio;
116095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						/* In the case where we try to read application data,
116195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						 * but we trigger an SSL handshake, we return -1 with
116295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						 * the retry option set.  Otherwise renegotiation may
116395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						 * cause nasty problems in the blocking world */
116495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						s->rwstate=SSL_READING;
116595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						bio=SSL_get_rbio(s);
116695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						BIO_clear_retry_flags(bio);
116795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						BIO_set_retry_read(bio);
116895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						return(-1);
116995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						}
117095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					}
117195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
117295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
117395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* we either finished a handshake or ignored the request,
117495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * now try again to obtain the (application) data we were asked for */
117595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto start;
117695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
117795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* If we are a server and get a client hello when renegotiation isn't
117895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * allowed send back a no renegotiation alert and carry on.
117995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * WARNING: experimental code, needs reviewing (steve)
118095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 */
118195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->server &&
118295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		SSL_is_init_finished(s) &&
118395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    		!s->s3->send_connection_binding &&
118495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->version > SSL3_VERSION) &&
118595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->s3->handshake_fragment_len >= 4) &&
118695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
118795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(s->session != NULL) && (s->session->cipher != NULL) &&
118895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		!(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
118995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
119095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
119195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/*s->s3->handshake_fragment_len = 0;*/
119295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rr->length = 0;
119395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ssl3_send_alert(s,SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
119495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto start;
119595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
119695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->s3->alert_fragment_len >= 2)
119795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
119895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		int alert_level = s->s3->alert_fragment[0];
119995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		int alert_descr = s->s3->alert_fragment[1];
120095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
120195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->s3->alert_fragment_len = 0;
120295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
120395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->msg_callback)
120495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->msg_callback(0, s->version, SSL3_RT_ALERT, s->s3->alert_fragment, 2, s, s->msg_callback_arg);
120595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
120695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->info_callback != NULL)
120795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			cb=s->info_callback;
120895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (s->ctx->info_callback != NULL)
120995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			cb=s->ctx->info_callback;
121095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
121195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (cb != NULL)
121295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
121395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			j = (alert_level << 8) | alert_descr;
121495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			cb(s, SSL_CB_READ_ALERT, j);
121595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
121695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
121795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (alert_level == 1) /* warning */
121895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
121995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->s3->warn_alert = alert_descr;
122095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (alert_descr == SSL_AD_CLOSE_NOTIFY)
122195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
122295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				s->shutdown |= SSL_RECEIVED_SHUTDOWN;
122395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				return(0);
122495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
122595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			/* This is a warning but we receive it if we requested
122695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * renegotiation and the peer denied it. Terminate with
122795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * a fatal alert because if application tried to
122895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * renegotiatie it presumably had a good reason and
122995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * expects it to succeed.
123095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 *
123195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * In future we might have a renegotiation where we
123295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 * don't care if the peer refused it where we carry on.
123395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			 */
123495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			else if (alert_descr == SSL_AD_NO_RENEGOTIATION)
123595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
123695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				al = SSL_AD_HANDSHAKE_FAILURE;
123795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_NO_RENEGOTIATION);
123895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto f_err;
123995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
124095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#ifdef SSL_AD_MISSING_SRP_USERNAME
124195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
124295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				return(0);
124395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
124495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
124595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (alert_level == 2) /* fatal */
124695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
124795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			char tmp[16];
124895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
124995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->rwstate=SSL_NOTHING;
125095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->s3->fatal_alert = alert_descr;
125195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_AD_REASON_OFFSET + alert_descr);
125295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
125395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			ERR_add_error_data(2,"SSL alert number ",tmp);
125495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->shutdown|=SSL_RECEIVED_SHUTDOWN;
125595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			SSL_CTX_remove_session(s->ctx,s->session);
125695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(0);
125795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
125895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
125995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
126095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			al=SSL_AD_ILLEGAL_PARAMETER;
126195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_UNKNOWN_ALERT_TYPE);
126295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto f_err;
126395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
126495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
126595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto start;
126695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
126795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
126895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
126995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
127095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->rwstate=SSL_NOTHING;
127195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rr->length=0;
127295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return(0);
127395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
127495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
127595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
127695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
127795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* 'Change Cipher Spec' is just a single byte, so we know
127895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * exactly what the record payload has to look like */
127995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (	(rr->length != 1) || (rr->off != 0) ||
128095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			(rr->data[0] != SSL3_MT_CCS))
128195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
128295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			al=SSL_AD_ILLEGAL_PARAMETER;
128395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_BAD_CHANGE_CIPHER_SPEC);
128495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto f_err;
128595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
128695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
128795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* Check we have a cipher to change to */
128895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->s3->tmp.new_cipher == NULL)
128995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
129095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			al=SSL_AD_UNEXPECTED_MESSAGE;
129195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_CCS_RECEIVED_EARLY);
129295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto f_err;
129395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
129495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
129586271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		if (!(s->s3->flags & SSL3_FLAGS_EXPECT_CCS))
1296ce7f9caa98fc62afd5fc40c0f13bc51bef2e7fa1Adam Langley			{
1297ce7f9caa98fc62afd5fc40c0f13bc51bef2e7fa1Adam Langley			al=SSL_AD_UNEXPECTED_MESSAGE;
1298ce7f9caa98fc62afd5fc40c0f13bc51bef2e7fa1Adam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_CCS_RECEIVED_EARLY);
1299ce7f9caa98fc62afd5fc40c0f13bc51bef2e7fa1Adam Langley			goto f_err;
1300ce7f9caa98fc62afd5fc40c0f13bc51bef2e7fa1Adam Langley			}
1301ce7f9caa98fc62afd5fc40c0f13bc51bef2e7fa1Adam Langley
130286271ee9f866cd83d9e37ab1ba1218ebefb336aaDavid Benjamin		s->s3->flags &= ~SSL3_FLAGS_EXPECT_CCS;
1303ce7f9caa98fc62afd5fc40c0f13bc51bef2e7fa1Adam Langley
130495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rr->length=0;
130595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
130695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->msg_callback)
130795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, s->msg_callback_arg);
130895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
130995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->s3->change_cipher_spec=1;
131095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!ssl3_do_change_cipher_spec(s))
131195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
131295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
131395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto start;
131495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
131595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
131695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Unexpected handshake message (Client Hello, or protocol violation) */
131795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((s->s3->handshake_fragment_len >= 4) &&	!s->in_handshake)
131895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
131995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
132095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
132195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
132295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if 0 /* worked only because C operator preferences are not as expected (and
132395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley       * because this is not really needed for clients except for detecting
132495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley       * protocol violations): */
132595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->state=SSL_ST_BEFORE|(s->server)
132695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				?SSL_ST_ACCEPT
132795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				:SSL_ST_CONNECT;
132895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#else
132995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
133095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
133195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->renegotiate=1;
133295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->new_session=1;
133395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
133495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		i=s->handshake_func(s);
133595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i < 0) return(i);
133695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (i == 0)
133795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
133895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
133995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(-1);
134095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
134195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
134295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!(s->mode & SSL_MODE_AUTO_RETRY))
134395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
134495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (s->s3->rbuf.left == 0) /* no read-ahead left? */
134595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
134695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				BIO *bio;
134795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				/* In the case where we try to read application data,
134895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * but we trigger an SSL handshake, we return -1 with
134995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * the retry option set.  Otherwise renegotiation may
135095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				 * cause nasty problems in the blocking world */
135195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				s->rwstate=SSL_READING;
135295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				bio=SSL_get_rbio(s);
135395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				BIO_clear_retry_flags(bio);
135495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				BIO_set_retry_read(bio);
135595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				return(-1);
135695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
135795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
135895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto start;
135995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
136095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
136195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	switch (rr->type)
136295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
136395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	default:
136495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* TLS up to v1.1 just ignores unknown message types:
136595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * TLS v1.2 give an unexpected message alert.
136695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 */
136795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION)
136895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
136995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			rr->length = 0;
137095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto start;
137195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
137295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		al=SSL_AD_UNEXPECTED_MESSAGE;
137395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_UNEXPECTED_RECORD);
137495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto f_err;
137595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case SSL3_RT_CHANGE_CIPHER_SPEC:
137695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case SSL3_RT_ALERT:
137795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case SSL3_RT_HANDSHAKE:
137895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* we already handled all of these, with the possible exception
137995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
138095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * should not happen when type != rr->type */
138195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		al=SSL_AD_UNEXPECTED_MESSAGE;
138295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, ERR_R_INTERNAL_ERROR);
138395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto f_err;
138495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case SSL3_RT_APPLICATION_DATA:
138595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* At this point, we were expecting handshake data,
138695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * but have application data.  If the library was
138795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * running inside ssl3_read() (i.e. in_read_app_data
138895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * is set) and it makes sense to read application data
138995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * at this point (session renegotiation not yet started),
139095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * we will indulge it.
139195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 */
139295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->s3->in_read_app_data &&
139395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			(s->s3->total_renegotiations != 0) &&
139495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			((
139595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				(s->state & SSL_ST_CONNECT) &&
139695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
139795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				(s->state <= SSL3_ST_CR_SRVR_HELLO_A)
139895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				) || (
139995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					(s->state & SSL_ST_ACCEPT) &&
140095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
140195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					(s->state >= SSL3_ST_SR_CLNT_HELLO_A)
140295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					)
140395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				))
140495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
140595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->s3->in_read_app_data=2;
140695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return(-1);
140795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
140895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
140995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
141095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			al=SSL_AD_UNEXPECTED_MESSAGE;
141195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_UNEXPECTED_RECORD);
141295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto f_err;
141395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
141495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
141595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* not reached */
141695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
141795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyf_err:
141895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ssl3_send_alert(s,SSL3_AL_FATAL,al);
141995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr:
142095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return(-1);
142195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
142295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
142395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ssl3_do_change_cipher_spec(SSL *s)
142495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
142595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i;
142695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
142795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->state & SSL_ST_ACCEPT)
142895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		i=SSL3_CHANGE_CIPHER_SERVER_READ;
142995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
143095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		i=SSL3_CHANGE_CIPHER_CLIENT_READ;
143195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
143295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->s3->tmp.key_block == NULL)
143395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
1434ec48ffc1fe525fddf6f69a6d0722a5f9ce532737Adam Langley		if (s->session == NULL || s->session->master_key_length == 0)
143595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
143695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			/* might happen if dtls1_read_bytes() calls this */
143795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(SSL, ssl3_do_change_cipher_spec, SSL_R_CCS_RECEIVED_EARLY);
143895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return (0);
143995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
144095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
144195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->session->cipher=s->s3->tmp.new_cipher;
144295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!s->method->ssl3_enc->setup_key_block(s)) return(0);
144395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
144495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
144595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!s->method->ssl3_enc->change_cipher_state(s,i))
144695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return(0);
144795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
144895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return(1);
144995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
145095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
145195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ssl3_send_alert(SSL *s, int level, int desc)
145295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
145395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Map tls/ssl alert value to correct one */
145495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	desc=s->method->ssl3_enc->alert_value(desc);
145595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
145695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have protocol_version alerts */
145795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (desc < 0) return -1;
145895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* If a fatal one, remove from cache */
145995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((level == 2) && (s->session != NULL))
146095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		SSL_CTX_remove_session(s->ctx,s->session);
146195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
146295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->alert_dispatch=1;
146395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->send_alert[0]=level;
146495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->send_alert[1]=desc;
146595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (s->s3->wbuf.left == 0) /* data still being written out? */
146695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return s->method->ssl_dispatch_alert(s);
146795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* else data is still being written out, we will get written
146895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 * some time in the future */
146995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return -1;
147095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
147195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
147295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ssl3_dispatch_alert(SSL *s)
147395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
147495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i,j;
147595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	void (*cb)(const SSL *ssl,int type,int val)=NULL;
147695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
147795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	s->s3->alert_dispatch=0;
1478d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley	i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0, 0);
147995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (i <= 0)
148095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
148195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		s->s3->alert_dispatch=1;
148295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
148395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
148495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
148595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* Alert sent to BIO.  If it is important, flush it now.
148695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * If the message does not get sent due to non-blocking IO,
148795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * we will not worry too much. */
148895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->s3->send_alert[0] == SSL3_AL_FATAL)
148995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			(void)BIO_flush(s->wbio);
149095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
149195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->msg_callback)
149295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s, s->msg_callback_arg);
149395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
149495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (s->info_callback != NULL)
149595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			cb=s->info_callback;
149695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (s->ctx->info_callback != NULL)
149795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			cb=s->ctx->info_callback;
149895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
149995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (cb != NULL)
150095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
150195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
150295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			cb(s,SSL_CB_WRITE_ALERT,j);
150395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
150495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
150595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return(i);
150695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
1507