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