1*0Sstevel@tonic-gate /* ssl/s3_pkt.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate /* ==================================================================== 59*0Sstevel@tonic-gate * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 60*0Sstevel@tonic-gate * 61*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 62*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 63*0Sstevel@tonic-gate * are met: 64*0Sstevel@tonic-gate * 65*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 66*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 67*0Sstevel@tonic-gate * 68*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 69*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 70*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 71*0Sstevel@tonic-gate * distribution. 72*0Sstevel@tonic-gate * 73*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 74*0Sstevel@tonic-gate * software must display the following acknowledgment: 75*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 76*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77*0Sstevel@tonic-gate * 78*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79*0Sstevel@tonic-gate * endorse or promote products derived from this software without 80*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 81*0Sstevel@tonic-gate * openssl-core@openssl.org. 82*0Sstevel@tonic-gate * 83*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 84*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 85*0Sstevel@tonic-gate * permission of the OpenSSL Project. 86*0Sstevel@tonic-gate * 87*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 88*0Sstevel@tonic-gate * acknowledgment: 89*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 90*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91*0Sstevel@tonic-gate * 92*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 104*0Sstevel@tonic-gate * ==================================================================== 105*0Sstevel@tonic-gate * 106*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 107*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 108*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 109*0Sstevel@tonic-gate * 110*0Sstevel@tonic-gate */ 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate #include <stdio.h> 113*0Sstevel@tonic-gate #include <errno.h> 114*0Sstevel@tonic-gate #define USE_SOCKETS 115*0Sstevel@tonic-gate #include "ssl_locl.h" 116*0Sstevel@tonic-gate #include <openssl/evp.h> 117*0Sstevel@tonic-gate #include <openssl/buffer.h> 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, 120*0Sstevel@tonic-gate unsigned int len, int create_empty_fragment); 121*0Sstevel@tonic-gate static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, 122*0Sstevel@tonic-gate unsigned int len); 123*0Sstevel@tonic-gate static int ssl3_get_record(SSL *s); 124*0Sstevel@tonic-gate static int do_compress(SSL *ssl); 125*0Sstevel@tonic-gate static int do_uncompress(SSL *ssl); 126*0Sstevel@tonic-gate static int do_change_cipher_spec(SSL *ssl); 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate /* used only by ssl3_get_record */ 129*0Sstevel@tonic-gate static int ssl3_read_n(SSL *s, int n, int max, int extend) 130*0Sstevel@tonic-gate { 131*0Sstevel@tonic-gate /* If extend == 0, obtain new n-byte packet; if extend == 1, increase 132*0Sstevel@tonic-gate * packet by another n bytes. 133*0Sstevel@tonic-gate * The packet will be in the sub-array of s->s3->rbuf.buf specified 134*0Sstevel@tonic-gate * by s->packet and s->packet_length. 135*0Sstevel@tonic-gate * (If s->read_ahead is set, 'max' bytes may be stored in rbuf 136*0Sstevel@tonic-gate * [plus s->packet_length bytes if extend == 1].) 137*0Sstevel@tonic-gate */ 138*0Sstevel@tonic-gate int i,off,newb; 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate if (!extend) 141*0Sstevel@tonic-gate { 142*0Sstevel@tonic-gate /* start with empty packet ... */ 143*0Sstevel@tonic-gate if (s->s3->rbuf.left == 0) 144*0Sstevel@tonic-gate s->s3->rbuf.offset = 0; 145*0Sstevel@tonic-gate s->packet = s->s3->rbuf.buf + s->s3->rbuf.offset; 146*0Sstevel@tonic-gate s->packet_length = 0; 147*0Sstevel@tonic-gate /* ... now we can act as if 'extend' was set */ 148*0Sstevel@tonic-gate } 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate /* if there is enough in the buffer from a previous read, take some */ 151*0Sstevel@tonic-gate if (s->s3->rbuf.left >= (int)n) 152*0Sstevel@tonic-gate { 153*0Sstevel@tonic-gate s->packet_length+=n; 154*0Sstevel@tonic-gate s->s3->rbuf.left-=n; 155*0Sstevel@tonic-gate s->s3->rbuf.offset+=n; 156*0Sstevel@tonic-gate return(n); 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate /* else we need to read more data */ 160*0Sstevel@tonic-gate if (!s->read_ahead) 161*0Sstevel@tonic-gate max=n; 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate { 164*0Sstevel@tonic-gate /* avoid buffer overflow */ 165*0Sstevel@tonic-gate int max_max = s->s3->rbuf.len - s->packet_length; 166*0Sstevel@tonic-gate if (max > max_max) 167*0Sstevel@tonic-gate max = max_max; 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate if (n > max) /* does not happen */ 170*0Sstevel@tonic-gate { 171*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR); 172*0Sstevel@tonic-gate return -1; 173*0Sstevel@tonic-gate } 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate off = s->packet_length; 176*0Sstevel@tonic-gate newb = s->s3->rbuf.left; 177*0Sstevel@tonic-gate /* Move any available bytes to front of buffer: 178*0Sstevel@tonic-gate * 'off' bytes already pointed to by 'packet', 179*0Sstevel@tonic-gate * 'newb' extra ones at the end */ 180*0Sstevel@tonic-gate if (s->packet != s->s3->rbuf.buf) 181*0Sstevel@tonic-gate { 182*0Sstevel@tonic-gate /* off > 0 */ 183*0Sstevel@tonic-gate memmove(s->s3->rbuf.buf, s->packet, off+newb); 184*0Sstevel@tonic-gate s->packet = s->s3->rbuf.buf; 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate while (newb < n) 188*0Sstevel@tonic-gate { 189*0Sstevel@tonic-gate /* Now we have off+newb bytes at the front of s->s3->rbuf.buf and need 190*0Sstevel@tonic-gate * to read in more until we have off+n (up to off+max if possible) */ 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate clear_sys_error(); 193*0Sstevel@tonic-gate if (s->rbio != NULL) 194*0Sstevel@tonic-gate { 195*0Sstevel@tonic-gate s->rwstate=SSL_READING; 196*0Sstevel@tonic-gate i=BIO_read(s->rbio, &(s->s3->rbuf.buf[off+newb]), max-newb); 197*0Sstevel@tonic-gate } 198*0Sstevel@tonic-gate else 199*0Sstevel@tonic-gate { 200*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_N,SSL_R_READ_BIO_NOT_SET); 201*0Sstevel@tonic-gate i = -1; 202*0Sstevel@tonic-gate } 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate if (i <= 0) 205*0Sstevel@tonic-gate { 206*0Sstevel@tonic-gate s->s3->rbuf.left = newb; 207*0Sstevel@tonic-gate return(i); 208*0Sstevel@tonic-gate } 209*0Sstevel@tonic-gate newb+=i; 210*0Sstevel@tonic-gate } 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate /* done reading, now the book-keeping */ 213*0Sstevel@tonic-gate s->s3->rbuf.offset = off + n; 214*0Sstevel@tonic-gate s->s3->rbuf.left = newb - n; 215*0Sstevel@tonic-gate s->packet_length += n; 216*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 217*0Sstevel@tonic-gate return(n); 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate /* Call this to get a new input record. 221*0Sstevel@tonic-gate * It will return <= 0 if more data is needed, normally due to an error 222*0Sstevel@tonic-gate * or non-blocking IO. 223*0Sstevel@tonic-gate * When it finishes, one packet has been decoded and can be found in 224*0Sstevel@tonic-gate * ssl->s3->rrec.type - is the type of record 225*0Sstevel@tonic-gate * ssl->s3->rrec.data, - data 226*0Sstevel@tonic-gate * ssl->s3->rrec.length, - number of bytes 227*0Sstevel@tonic-gate */ 228*0Sstevel@tonic-gate /* used only by ssl3_read_bytes */ 229*0Sstevel@tonic-gate static int ssl3_get_record(SSL *s) 230*0Sstevel@tonic-gate { 231*0Sstevel@tonic-gate int ssl_major,ssl_minor,al; 232*0Sstevel@tonic-gate int enc_err,n,i,ret= -1; 233*0Sstevel@tonic-gate SSL3_RECORD *rr; 234*0Sstevel@tonic-gate SSL_SESSION *sess; 235*0Sstevel@tonic-gate unsigned char *p; 236*0Sstevel@tonic-gate unsigned char md[EVP_MAX_MD_SIZE]; 237*0Sstevel@tonic-gate short version; 238*0Sstevel@tonic-gate unsigned int mac_size; 239*0Sstevel@tonic-gate int clear=0; 240*0Sstevel@tonic-gate size_t extra; 241*0Sstevel@tonic-gate int decryption_failed_or_bad_record_mac = 0; 242*0Sstevel@tonic-gate unsigned char *mac = NULL; 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate rr= &(s->s3->rrec); 245*0Sstevel@tonic-gate sess=s->session; 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) 248*0Sstevel@tonic-gate extra=SSL3_RT_MAX_EXTRA; 249*0Sstevel@tonic-gate else 250*0Sstevel@tonic-gate extra=0; 251*0Sstevel@tonic-gate if (extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE) 252*0Sstevel@tonic-gate { 253*0Sstevel@tonic-gate /* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER 254*0Sstevel@tonic-gate * set after ssl3_setup_buffers() was done */ 255*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR); 256*0Sstevel@tonic-gate return -1; 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate again: 260*0Sstevel@tonic-gate /* check if we have the header */ 261*0Sstevel@tonic-gate if ( (s->rstate != SSL_ST_READ_BODY) || 262*0Sstevel@tonic-gate (s->packet_length < SSL3_RT_HEADER_LENGTH)) 263*0Sstevel@tonic-gate { 264*0Sstevel@tonic-gate n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); 265*0Sstevel@tonic-gate if (n <= 0) return(n); /* error or non-blocking */ 266*0Sstevel@tonic-gate s->rstate=SSL_ST_READ_BODY; 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate p=s->packet; 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate /* Pull apart the header into the SSL3_RECORD */ 271*0Sstevel@tonic-gate rr->type= *(p++); 272*0Sstevel@tonic-gate ssl_major= *(p++); 273*0Sstevel@tonic-gate ssl_minor= *(p++); 274*0Sstevel@tonic-gate version=(ssl_major<<8)|ssl_minor; 275*0Sstevel@tonic-gate n2s(p,rr->length); 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate /* Lets check version */ 278*0Sstevel@tonic-gate if (s->first_packet) 279*0Sstevel@tonic-gate { 280*0Sstevel@tonic-gate s->first_packet=0; 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate else 283*0Sstevel@tonic-gate { 284*0Sstevel@tonic-gate if (version != s->version) 285*0Sstevel@tonic-gate { 286*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); 287*0Sstevel@tonic-gate /* Send back error using their 288*0Sstevel@tonic-gate * version number :-) */ 289*0Sstevel@tonic-gate s->version=version; 290*0Sstevel@tonic-gate al=SSL_AD_PROTOCOL_VERSION; 291*0Sstevel@tonic-gate goto f_err; 292*0Sstevel@tonic-gate } 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate if ((version>>8) != SSL3_VERSION_MAJOR) 296*0Sstevel@tonic-gate { 297*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); 298*0Sstevel@tonic-gate goto err; 299*0Sstevel@tonic-gate } 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra) 302*0Sstevel@tonic-gate { 303*0Sstevel@tonic-gate al=SSL_AD_RECORD_OVERFLOW; 304*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG); 305*0Sstevel@tonic-gate goto f_err; 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate /* now s->rstate == SSL_ST_READ_BODY */ 309*0Sstevel@tonic-gate } 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate if (rr->length > s->packet_length-SSL3_RT_HEADER_LENGTH) 314*0Sstevel@tonic-gate { 315*0Sstevel@tonic-gate /* now s->packet_length == SSL3_RT_HEADER_LENGTH */ 316*0Sstevel@tonic-gate i=rr->length; 317*0Sstevel@tonic-gate n=ssl3_read_n(s,i,i,1); 318*0Sstevel@tonic-gate if (n <= 0) return(n); /* error or non-blocking io */ 319*0Sstevel@tonic-gate /* now n == rr->length, 320*0Sstevel@tonic-gate * and s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length */ 321*0Sstevel@tonic-gate } 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */ 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gate /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, 326*0Sstevel@tonic-gate * and we have that many bytes in s->packet 327*0Sstevel@tonic-gate */ 328*0Sstevel@tonic-gate rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]); 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate /* ok, we can now read from 's->packet' data into 'rr' 331*0Sstevel@tonic-gate * rr->input points at rr->length bytes, which 332*0Sstevel@tonic-gate * need to be copied into rr->data by either 333*0Sstevel@tonic-gate * the decryption or by the decompression 334*0Sstevel@tonic-gate * When the data is 'copied' into the rr->data buffer, 335*0Sstevel@tonic-gate * rr->input will be pointed at the new buffer */ 336*0Sstevel@tonic-gate 337*0Sstevel@tonic-gate /* We now have - encrypted [ MAC [ compressed [ plain ] ] ] 338*0Sstevel@tonic-gate * rr->length bytes of encrypted compressed stuff. */ 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate /* check is not needed I believe */ 341*0Sstevel@tonic-gate if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra) 342*0Sstevel@tonic-gate { 343*0Sstevel@tonic-gate al=SSL_AD_RECORD_OVERFLOW; 344*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG); 345*0Sstevel@tonic-gate goto f_err; 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate /* decrypt in place in 'rr->input' */ 349*0Sstevel@tonic-gate rr->data=rr->input; 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate enc_err = s->method->ssl3_enc->enc(s,0); 352*0Sstevel@tonic-gate if (enc_err <= 0) 353*0Sstevel@tonic-gate { 354*0Sstevel@tonic-gate if (enc_err == 0) 355*0Sstevel@tonic-gate /* SSLerr() and ssl3_send_alert() have been called */ 356*0Sstevel@tonic-gate goto err; 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate /* Otherwise enc_err == -1, which indicates bad padding 359*0Sstevel@tonic-gate * (rec->length has not been changed in this case). 360*0Sstevel@tonic-gate * To minimize information leaked via timing, we will perform 361*0Sstevel@tonic-gate * the MAC computation anyway. */ 362*0Sstevel@tonic-gate decryption_failed_or_bad_record_mac = 1; 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate #ifdef TLS_DEBUG 366*0Sstevel@tonic-gate printf("dec %d\n",rr->length); 367*0Sstevel@tonic-gate { unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); } 368*0Sstevel@tonic-gate printf("\n"); 369*0Sstevel@tonic-gate #endif 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate /* r->length is now the compressed data plus mac */ 372*0Sstevel@tonic-gate if ( (sess == NULL) || 373*0Sstevel@tonic-gate (s->enc_read_ctx == NULL) || 374*0Sstevel@tonic-gate (s->read_hash == NULL)) 375*0Sstevel@tonic-gate clear=1; 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate if (!clear) 378*0Sstevel@tonic-gate { 379*0Sstevel@tonic-gate mac_size=EVP_MD_size(s->read_hash); 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) 382*0Sstevel@tonic-gate { 383*0Sstevel@tonic-gate #if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ 384*0Sstevel@tonic-gate al=SSL_AD_RECORD_OVERFLOW; 385*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); 386*0Sstevel@tonic-gate goto f_err; 387*0Sstevel@tonic-gate #else 388*0Sstevel@tonic-gate decryption_failed_or_bad_record_mac = 1; 389*0Sstevel@tonic-gate #endif 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ 392*0Sstevel@tonic-gate if (rr->length >= mac_size) 393*0Sstevel@tonic-gate { 394*0Sstevel@tonic-gate rr->length -= mac_size; 395*0Sstevel@tonic-gate mac = &rr->data[rr->length]; 396*0Sstevel@tonic-gate } 397*0Sstevel@tonic-gate else 398*0Sstevel@tonic-gate { 399*0Sstevel@tonic-gate /* record (minus padding) is too short to contain a MAC */ 400*0Sstevel@tonic-gate #if 0 /* OK only for stream ciphers */ 401*0Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 402*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); 403*0Sstevel@tonic-gate goto f_err; 404*0Sstevel@tonic-gate #else 405*0Sstevel@tonic-gate decryption_failed_or_bad_record_mac = 1; 406*0Sstevel@tonic-gate rr->length = 0; 407*0Sstevel@tonic-gate #endif 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate i=s->method->ssl3_enc->mac(s,md,0); 410*0Sstevel@tonic-gate if (mac == NULL || memcmp(md, mac, mac_size) != 0) 411*0Sstevel@tonic-gate { 412*0Sstevel@tonic-gate decryption_failed_or_bad_record_mac = 1; 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate } 415*0Sstevel@tonic-gate 416*0Sstevel@tonic-gate if (decryption_failed_or_bad_record_mac) 417*0Sstevel@tonic-gate { 418*0Sstevel@tonic-gate /* A separate 'decryption_failed' alert was introduced with TLS 1.0, 419*0Sstevel@tonic-gate * SSL 3.0 only has 'bad_record_mac'. But unless a decryption 420*0Sstevel@tonic-gate * failure is directly visible from the ciphertext anyway, 421*0Sstevel@tonic-gate * we should not reveal which kind of error occured -- this 422*0Sstevel@tonic-gate * might become visible to an attacker (e.g. via a logfile) */ 423*0Sstevel@tonic-gate al=SSL_AD_BAD_RECORD_MAC; 424*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); 425*0Sstevel@tonic-gate goto f_err; 426*0Sstevel@tonic-gate } 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate /* r->length is now just compressed */ 429*0Sstevel@tonic-gate if (s->expand != NULL) 430*0Sstevel@tonic-gate { 431*0Sstevel@tonic-gate if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra) 432*0Sstevel@tonic-gate { 433*0Sstevel@tonic-gate al=SSL_AD_RECORD_OVERFLOW; 434*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG); 435*0Sstevel@tonic-gate goto f_err; 436*0Sstevel@tonic-gate } 437*0Sstevel@tonic-gate if (!do_uncompress(s)) 438*0Sstevel@tonic-gate { 439*0Sstevel@tonic-gate al=SSL_AD_DECOMPRESSION_FAILURE; 440*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION); 441*0Sstevel@tonic-gate goto f_err; 442*0Sstevel@tonic-gate } 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra) 446*0Sstevel@tonic-gate { 447*0Sstevel@tonic-gate al=SSL_AD_RECORD_OVERFLOW; 448*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG); 449*0Sstevel@tonic-gate goto f_err; 450*0Sstevel@tonic-gate } 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate rr->off=0; 453*0Sstevel@tonic-gate /* So at this point the following is true 454*0Sstevel@tonic-gate * ssl->s3->rrec.type is the type of record 455*0Sstevel@tonic-gate * ssl->s3->rrec.length == number of bytes in record 456*0Sstevel@tonic-gate * ssl->s3->rrec.off == offset to first valid byte 457*0Sstevel@tonic-gate * ssl->s3->rrec.data == where to take bytes from, increment 458*0Sstevel@tonic-gate * after use :-). 459*0Sstevel@tonic-gate */ 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate /* we have pulled in a full packet so zero things */ 462*0Sstevel@tonic-gate s->packet_length=0; 463*0Sstevel@tonic-gate 464*0Sstevel@tonic-gate /* just read a 0 length packet */ 465*0Sstevel@tonic-gate if (rr->length == 0) goto again; 466*0Sstevel@tonic-gate 467*0Sstevel@tonic-gate return(1); 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate f_err: 470*0Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,al); 471*0Sstevel@tonic-gate err: 472*0Sstevel@tonic-gate return(ret); 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate static int do_uncompress(SSL *ssl) 476*0Sstevel@tonic-gate { 477*0Sstevel@tonic-gate int i; 478*0Sstevel@tonic-gate SSL3_RECORD *rr; 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate rr= &(ssl->s3->rrec); 481*0Sstevel@tonic-gate i=COMP_expand_block(ssl->expand,rr->comp, 482*0Sstevel@tonic-gate SSL3_RT_MAX_PLAIN_LENGTH,rr->data,(int)rr->length); 483*0Sstevel@tonic-gate if (i < 0) 484*0Sstevel@tonic-gate return(0); 485*0Sstevel@tonic-gate else 486*0Sstevel@tonic-gate rr->length=i; 487*0Sstevel@tonic-gate rr->data=rr->comp; 488*0Sstevel@tonic-gate 489*0Sstevel@tonic-gate return(1); 490*0Sstevel@tonic-gate } 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate static int do_compress(SSL *ssl) 493*0Sstevel@tonic-gate { 494*0Sstevel@tonic-gate int i; 495*0Sstevel@tonic-gate SSL3_RECORD *wr; 496*0Sstevel@tonic-gate 497*0Sstevel@tonic-gate wr= &(ssl->s3->wrec); 498*0Sstevel@tonic-gate i=COMP_compress_block(ssl->compress,wr->data, 499*0Sstevel@tonic-gate SSL3_RT_MAX_COMPRESSED_LENGTH, 500*0Sstevel@tonic-gate wr->input,(int)wr->length); 501*0Sstevel@tonic-gate if (i < 0) 502*0Sstevel@tonic-gate return(0); 503*0Sstevel@tonic-gate else 504*0Sstevel@tonic-gate wr->length=i; 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gate wr->input=wr->data; 507*0Sstevel@tonic-gate return(1); 508*0Sstevel@tonic-gate } 509*0Sstevel@tonic-gate 510*0Sstevel@tonic-gate /* Call this to write data in records of type 'type' 511*0Sstevel@tonic-gate * It will return <= 0 if not all data has been sent or non-blocking IO. 512*0Sstevel@tonic-gate */ 513*0Sstevel@tonic-gate int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) 514*0Sstevel@tonic-gate { 515*0Sstevel@tonic-gate const unsigned char *buf=buf_; 516*0Sstevel@tonic-gate unsigned int tot,n,nw; 517*0Sstevel@tonic-gate int i; 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 520*0Sstevel@tonic-gate tot=s->s3->wnum; 521*0Sstevel@tonic-gate s->s3->wnum=0; 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate if (SSL_in_init(s) && !s->in_handshake) 524*0Sstevel@tonic-gate { 525*0Sstevel@tonic-gate i=s->handshake_func(s); 526*0Sstevel@tonic-gate if (i < 0) return(i); 527*0Sstevel@tonic-gate if (i == 0) 528*0Sstevel@tonic-gate { 529*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); 530*0Sstevel@tonic-gate return -1; 531*0Sstevel@tonic-gate } 532*0Sstevel@tonic-gate } 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate n=(len-tot); 535*0Sstevel@tonic-gate for (;;) 536*0Sstevel@tonic-gate { 537*0Sstevel@tonic-gate if (n > SSL3_RT_MAX_PLAIN_LENGTH) 538*0Sstevel@tonic-gate nw=SSL3_RT_MAX_PLAIN_LENGTH; 539*0Sstevel@tonic-gate else 540*0Sstevel@tonic-gate nw=n; 541*0Sstevel@tonic-gate 542*0Sstevel@tonic-gate i=do_ssl3_write(s, type, &(buf[tot]), nw, 0); 543*0Sstevel@tonic-gate if (i <= 0) 544*0Sstevel@tonic-gate { 545*0Sstevel@tonic-gate s->s3->wnum=tot; 546*0Sstevel@tonic-gate return i; 547*0Sstevel@tonic-gate } 548*0Sstevel@tonic-gate 549*0Sstevel@tonic-gate if ((i == (int)n) || 550*0Sstevel@tonic-gate (type == SSL3_RT_APPLICATION_DATA && 551*0Sstevel@tonic-gate (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) 552*0Sstevel@tonic-gate { 553*0Sstevel@tonic-gate /* next chunk of data should get another prepended empty fragment 554*0Sstevel@tonic-gate * in ciphersuites with known-IV weakness: */ 555*0Sstevel@tonic-gate s->s3->empty_fragment_done = 0; 556*0Sstevel@tonic-gate 557*0Sstevel@tonic-gate return tot+i; 558*0Sstevel@tonic-gate } 559*0Sstevel@tonic-gate 560*0Sstevel@tonic-gate n-=i; 561*0Sstevel@tonic-gate tot+=i; 562*0Sstevel@tonic-gate } 563*0Sstevel@tonic-gate } 564*0Sstevel@tonic-gate 565*0Sstevel@tonic-gate static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, 566*0Sstevel@tonic-gate unsigned int len, int create_empty_fragment) 567*0Sstevel@tonic-gate { 568*0Sstevel@tonic-gate unsigned char *p,*plen; 569*0Sstevel@tonic-gate int i,mac_size,clear=0; 570*0Sstevel@tonic-gate int prefix_len = 0; 571*0Sstevel@tonic-gate SSL3_RECORD *wr; 572*0Sstevel@tonic-gate SSL3_BUFFER *wb; 573*0Sstevel@tonic-gate SSL_SESSION *sess; 574*0Sstevel@tonic-gate 575*0Sstevel@tonic-gate /* first check if there is a SSL3_BUFFER still being written 576*0Sstevel@tonic-gate * out. This will happen with non blocking IO */ 577*0Sstevel@tonic-gate if (s->s3->wbuf.left != 0) 578*0Sstevel@tonic-gate return(ssl3_write_pending(s,type,buf,len)); 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gate /* If we have an alert to send, lets send it */ 581*0Sstevel@tonic-gate if (s->s3->alert_dispatch) 582*0Sstevel@tonic-gate { 583*0Sstevel@tonic-gate i=ssl3_dispatch_alert(s); 584*0Sstevel@tonic-gate if (i <= 0) 585*0Sstevel@tonic-gate return(i); 586*0Sstevel@tonic-gate /* if it went, fall through and send more stuff */ 587*0Sstevel@tonic-gate } 588*0Sstevel@tonic-gate 589*0Sstevel@tonic-gate if (len == 0 && !create_empty_fragment) 590*0Sstevel@tonic-gate return 0; 591*0Sstevel@tonic-gate 592*0Sstevel@tonic-gate wr= &(s->s3->wrec); 593*0Sstevel@tonic-gate wb= &(s->s3->wbuf); 594*0Sstevel@tonic-gate sess=s->session; 595*0Sstevel@tonic-gate 596*0Sstevel@tonic-gate if ( (sess == NULL) || 597*0Sstevel@tonic-gate (s->enc_write_ctx == NULL) || 598*0Sstevel@tonic-gate (s->write_hash == NULL)) 599*0Sstevel@tonic-gate clear=1; 600*0Sstevel@tonic-gate 601*0Sstevel@tonic-gate if (clear) 602*0Sstevel@tonic-gate mac_size=0; 603*0Sstevel@tonic-gate else 604*0Sstevel@tonic-gate mac_size=EVP_MD_size(s->write_hash); 605*0Sstevel@tonic-gate 606*0Sstevel@tonic-gate /* 'create_empty_fragment' is true only when this function calls itself */ 607*0Sstevel@tonic-gate if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) 608*0Sstevel@tonic-gate { 609*0Sstevel@tonic-gate /* countermeasure against known-IV weakness in CBC ciphersuites 610*0Sstevel@tonic-gate * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ 611*0Sstevel@tonic-gate 612*0Sstevel@tonic-gate if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) 613*0Sstevel@tonic-gate { 614*0Sstevel@tonic-gate /* recursive function call with 'create_empty_fragment' set; 615*0Sstevel@tonic-gate * this prepares and buffers the data for an empty fragment 616*0Sstevel@tonic-gate * (these 'prefix_len' bytes are sent out later 617*0Sstevel@tonic-gate * together with the actual payload) */ 618*0Sstevel@tonic-gate prefix_len = do_ssl3_write(s, type, buf, 0, 1); 619*0Sstevel@tonic-gate if (prefix_len <= 0) 620*0Sstevel@tonic-gate goto err; 621*0Sstevel@tonic-gate 622*0Sstevel@tonic-gate if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) 623*0Sstevel@tonic-gate { 624*0Sstevel@tonic-gate /* insufficient space */ 625*0Sstevel@tonic-gate SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); 626*0Sstevel@tonic-gate goto err; 627*0Sstevel@tonic-gate } 628*0Sstevel@tonic-gate } 629*0Sstevel@tonic-gate 630*0Sstevel@tonic-gate s->s3->empty_fragment_done = 1; 631*0Sstevel@tonic-gate } 632*0Sstevel@tonic-gate 633*0Sstevel@tonic-gate p = wb->buf + prefix_len; 634*0Sstevel@tonic-gate 635*0Sstevel@tonic-gate /* write the header */ 636*0Sstevel@tonic-gate 637*0Sstevel@tonic-gate *(p++)=type&0xff; 638*0Sstevel@tonic-gate wr->type=type; 639*0Sstevel@tonic-gate 640*0Sstevel@tonic-gate *(p++)=(s->version>>8); 641*0Sstevel@tonic-gate *(p++)=s->version&0xff; 642*0Sstevel@tonic-gate 643*0Sstevel@tonic-gate /* field where we are to write out packet length */ 644*0Sstevel@tonic-gate plen=p; 645*0Sstevel@tonic-gate p+=2; 646*0Sstevel@tonic-gate 647*0Sstevel@tonic-gate /* lets setup the record stuff. */ 648*0Sstevel@tonic-gate wr->data=p; 649*0Sstevel@tonic-gate wr->length=(int)len; 650*0Sstevel@tonic-gate wr->input=(unsigned char *)buf; 651*0Sstevel@tonic-gate 652*0Sstevel@tonic-gate /* we now 'read' from wr->input, wr->length bytes into 653*0Sstevel@tonic-gate * wr->data */ 654*0Sstevel@tonic-gate 655*0Sstevel@tonic-gate /* first we compress */ 656*0Sstevel@tonic-gate if (s->compress != NULL) 657*0Sstevel@tonic-gate { 658*0Sstevel@tonic-gate if (!do_compress(s)) 659*0Sstevel@tonic-gate { 660*0Sstevel@tonic-gate SSLerr(SSL_F_DO_SSL3_WRITE,SSL_R_COMPRESSION_FAILURE); 661*0Sstevel@tonic-gate goto err; 662*0Sstevel@tonic-gate } 663*0Sstevel@tonic-gate } 664*0Sstevel@tonic-gate else 665*0Sstevel@tonic-gate { 666*0Sstevel@tonic-gate memcpy(wr->data,wr->input,wr->length); 667*0Sstevel@tonic-gate wr->input=wr->data; 668*0Sstevel@tonic-gate } 669*0Sstevel@tonic-gate 670*0Sstevel@tonic-gate /* we should still have the output to wr->data and the input 671*0Sstevel@tonic-gate * from wr->input. Length should be wr->length. 672*0Sstevel@tonic-gate * wr->data still points in the wb->buf */ 673*0Sstevel@tonic-gate 674*0Sstevel@tonic-gate if (mac_size != 0) 675*0Sstevel@tonic-gate { 676*0Sstevel@tonic-gate s->method->ssl3_enc->mac(s,&(p[wr->length]),1); 677*0Sstevel@tonic-gate wr->length+=mac_size; 678*0Sstevel@tonic-gate wr->input=p; 679*0Sstevel@tonic-gate wr->data=p; 680*0Sstevel@tonic-gate } 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate /* ssl3_enc can only have an error on read */ 683*0Sstevel@tonic-gate s->method->ssl3_enc->enc(s,1); 684*0Sstevel@tonic-gate 685*0Sstevel@tonic-gate /* record length after mac and block padding */ 686*0Sstevel@tonic-gate s2n(wr->length,plen); 687*0Sstevel@tonic-gate 688*0Sstevel@tonic-gate /* we should now have 689*0Sstevel@tonic-gate * wr->data pointing to the encrypted data, which is 690*0Sstevel@tonic-gate * wr->length long */ 691*0Sstevel@tonic-gate wr->type=type; /* not needed but helps for debugging */ 692*0Sstevel@tonic-gate wr->length+=SSL3_RT_HEADER_LENGTH; 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gate if (create_empty_fragment) 695*0Sstevel@tonic-gate { 696*0Sstevel@tonic-gate /* we are in a recursive call; 697*0Sstevel@tonic-gate * just return the length, don't write out anything here 698*0Sstevel@tonic-gate */ 699*0Sstevel@tonic-gate return wr->length; 700*0Sstevel@tonic-gate } 701*0Sstevel@tonic-gate 702*0Sstevel@tonic-gate /* now let's set up wb */ 703*0Sstevel@tonic-gate wb->left = prefix_len + wr->length; 704*0Sstevel@tonic-gate wb->offset = 0; 705*0Sstevel@tonic-gate 706*0Sstevel@tonic-gate /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ 707*0Sstevel@tonic-gate s->s3->wpend_tot=len; 708*0Sstevel@tonic-gate s->s3->wpend_buf=buf; 709*0Sstevel@tonic-gate s->s3->wpend_type=type; 710*0Sstevel@tonic-gate s->s3->wpend_ret=len; 711*0Sstevel@tonic-gate 712*0Sstevel@tonic-gate /* we now just need to write the buffer */ 713*0Sstevel@tonic-gate return ssl3_write_pending(s,type,buf,len); 714*0Sstevel@tonic-gate err: 715*0Sstevel@tonic-gate return -1; 716*0Sstevel@tonic-gate } 717*0Sstevel@tonic-gate 718*0Sstevel@tonic-gate /* if s->s3->wbuf.left != 0, we need to call this */ 719*0Sstevel@tonic-gate static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, 720*0Sstevel@tonic-gate unsigned int len) 721*0Sstevel@tonic-gate { 722*0Sstevel@tonic-gate int i; 723*0Sstevel@tonic-gate 724*0Sstevel@tonic-gate /* XXXX */ 725*0Sstevel@tonic-gate if ((s->s3->wpend_tot > (int)len) 726*0Sstevel@tonic-gate || ((s->s3->wpend_buf != buf) && 727*0Sstevel@tonic-gate !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) 728*0Sstevel@tonic-gate || (s->s3->wpend_type != type)) 729*0Sstevel@tonic-gate { 730*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY); 731*0Sstevel@tonic-gate return(-1); 732*0Sstevel@tonic-gate } 733*0Sstevel@tonic-gate 734*0Sstevel@tonic-gate for (;;) 735*0Sstevel@tonic-gate { 736*0Sstevel@tonic-gate clear_sys_error(); 737*0Sstevel@tonic-gate if (s->wbio != NULL) 738*0Sstevel@tonic-gate { 739*0Sstevel@tonic-gate s->rwstate=SSL_WRITING; 740*0Sstevel@tonic-gate i=BIO_write(s->wbio, 741*0Sstevel@tonic-gate (char *)&(s->s3->wbuf.buf[s->s3->wbuf.offset]), 742*0Sstevel@tonic-gate (unsigned int)s->s3->wbuf.left); 743*0Sstevel@tonic-gate } 744*0Sstevel@tonic-gate else 745*0Sstevel@tonic-gate { 746*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET); 747*0Sstevel@tonic-gate i= -1; 748*0Sstevel@tonic-gate } 749*0Sstevel@tonic-gate if (i == s->s3->wbuf.left) 750*0Sstevel@tonic-gate { 751*0Sstevel@tonic-gate s->s3->wbuf.left=0; 752*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 753*0Sstevel@tonic-gate return(s->s3->wpend_ret); 754*0Sstevel@tonic-gate } 755*0Sstevel@tonic-gate else if (i <= 0) 756*0Sstevel@tonic-gate return(i); 757*0Sstevel@tonic-gate s->s3->wbuf.offset+=i; 758*0Sstevel@tonic-gate s->s3->wbuf.left-=i; 759*0Sstevel@tonic-gate } 760*0Sstevel@tonic-gate } 761*0Sstevel@tonic-gate 762*0Sstevel@tonic-gate /* Return up to 'len' payload bytes received in 'type' records. 763*0Sstevel@tonic-gate * 'type' is one of the following: 764*0Sstevel@tonic-gate * 765*0Sstevel@tonic-gate * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) 766*0Sstevel@tonic-gate * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) 767*0Sstevel@tonic-gate * - 0 (during a shutdown, no data has to be returned) 768*0Sstevel@tonic-gate * 769*0Sstevel@tonic-gate * If we don't have stored data to work from, read a SSL/TLS record first 770*0Sstevel@tonic-gate * (possibly multiple records if we still don't have anything to return). 771*0Sstevel@tonic-gate * 772*0Sstevel@tonic-gate * This function must handle any surprises the peer may have for us, such as 773*0Sstevel@tonic-gate * Alert records (e.g. close_notify), ChangeCipherSpec records (not really 774*0Sstevel@tonic-gate * a surprise, but handled as if it were), or renegotiation requests. 775*0Sstevel@tonic-gate * Also if record payloads contain fragments too small to process, we store 776*0Sstevel@tonic-gate * them until there is enough for the respective protocol (the record protocol 777*0Sstevel@tonic-gate * may use arbitrary fragmentation and even interleaving): 778*0Sstevel@tonic-gate * Change cipher spec protocol 779*0Sstevel@tonic-gate * just 1 byte needed, no need for keeping anything stored 780*0Sstevel@tonic-gate * Alert protocol 781*0Sstevel@tonic-gate * 2 bytes needed (AlertLevel, AlertDescription) 782*0Sstevel@tonic-gate * Handshake protocol 783*0Sstevel@tonic-gate * 4 bytes needed (HandshakeType, uint24 length) -- we just have 784*0Sstevel@tonic-gate * to detect unexpected Client Hello and Hello Request messages 785*0Sstevel@tonic-gate * here, anything else is handled by higher layers 786*0Sstevel@tonic-gate * Application data protocol 787*0Sstevel@tonic-gate * none of our business 788*0Sstevel@tonic-gate */ 789*0Sstevel@tonic-gate int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) 790*0Sstevel@tonic-gate { 791*0Sstevel@tonic-gate int al,i,j,ret; 792*0Sstevel@tonic-gate unsigned int n; 793*0Sstevel@tonic-gate SSL3_RECORD *rr; 794*0Sstevel@tonic-gate void (*cb)(const SSL *ssl,int type2,int val)=NULL; 795*0Sstevel@tonic-gate 796*0Sstevel@tonic-gate if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ 797*0Sstevel@tonic-gate if (!ssl3_setup_buffers(s)) 798*0Sstevel@tonic-gate return(-1); 799*0Sstevel@tonic-gate 800*0Sstevel@tonic-gate if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) || 801*0Sstevel@tonic-gate (peek && (type != SSL3_RT_APPLICATION_DATA))) 802*0Sstevel@tonic-gate { 803*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); 804*0Sstevel@tonic-gate return -1; 805*0Sstevel@tonic-gate } 806*0Sstevel@tonic-gate 807*0Sstevel@tonic-gate if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0)) 808*0Sstevel@tonic-gate /* (partially) satisfy request from storage */ 809*0Sstevel@tonic-gate { 810*0Sstevel@tonic-gate unsigned char *src = s->s3->handshake_fragment; 811*0Sstevel@tonic-gate unsigned char *dst = buf; 812*0Sstevel@tonic-gate unsigned int k; 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gate /* peek == 0 */ 815*0Sstevel@tonic-gate n = 0; 816*0Sstevel@tonic-gate while ((len > 0) && (s->s3->handshake_fragment_len > 0)) 817*0Sstevel@tonic-gate { 818*0Sstevel@tonic-gate *dst++ = *src++; 819*0Sstevel@tonic-gate len--; s->s3->handshake_fragment_len--; 820*0Sstevel@tonic-gate n++; 821*0Sstevel@tonic-gate } 822*0Sstevel@tonic-gate /* move any remaining fragment bytes: */ 823*0Sstevel@tonic-gate for (k = 0; k < s->s3->handshake_fragment_len; k++) 824*0Sstevel@tonic-gate s->s3->handshake_fragment[k] = *src++; 825*0Sstevel@tonic-gate return n; 826*0Sstevel@tonic-gate } 827*0Sstevel@tonic-gate 828*0Sstevel@tonic-gate /* Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */ 829*0Sstevel@tonic-gate 830*0Sstevel@tonic-gate if (!s->in_handshake && SSL_in_init(s)) 831*0Sstevel@tonic-gate { 832*0Sstevel@tonic-gate /* type == SSL3_RT_APPLICATION_DATA */ 833*0Sstevel@tonic-gate i=s->handshake_func(s); 834*0Sstevel@tonic-gate if (i < 0) return(i); 835*0Sstevel@tonic-gate if (i == 0) 836*0Sstevel@tonic-gate { 837*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); 838*0Sstevel@tonic-gate return(-1); 839*0Sstevel@tonic-gate } 840*0Sstevel@tonic-gate } 841*0Sstevel@tonic-gate start: 842*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 843*0Sstevel@tonic-gate 844*0Sstevel@tonic-gate /* s->s3->rrec.type - is the type of record 845*0Sstevel@tonic-gate * s->s3->rrec.data, - data 846*0Sstevel@tonic-gate * s->s3->rrec.off, - offset into 'data' for next read 847*0Sstevel@tonic-gate * s->s3->rrec.length, - number of bytes. */ 848*0Sstevel@tonic-gate rr = &(s->s3->rrec); 849*0Sstevel@tonic-gate 850*0Sstevel@tonic-gate /* get new packet if necessary */ 851*0Sstevel@tonic-gate if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) 852*0Sstevel@tonic-gate { 853*0Sstevel@tonic-gate ret=ssl3_get_record(s); 854*0Sstevel@tonic-gate if (ret <= 0) return(ret); 855*0Sstevel@tonic-gate } 856*0Sstevel@tonic-gate 857*0Sstevel@tonic-gate /* we now have a packet which can be read and processed */ 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, 860*0Sstevel@tonic-gate * reset by ssl3_get_finished */ 861*0Sstevel@tonic-gate && (rr->type != SSL3_RT_HANDSHAKE)) 862*0Sstevel@tonic-gate { 863*0Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE; 864*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); 865*0Sstevel@tonic-gate goto err; 866*0Sstevel@tonic-gate } 867*0Sstevel@tonic-gate 868*0Sstevel@tonic-gate /* If the other end has shut down, throw anything we read away 869*0Sstevel@tonic-gate * (even in 'peek' mode) */ 870*0Sstevel@tonic-gate if (s->shutdown & SSL_RECEIVED_SHUTDOWN) 871*0Sstevel@tonic-gate { 872*0Sstevel@tonic-gate rr->length=0; 873*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 874*0Sstevel@tonic-gate return(0); 875*0Sstevel@tonic-gate } 876*0Sstevel@tonic-gate 877*0Sstevel@tonic-gate 878*0Sstevel@tonic-gate if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ 879*0Sstevel@tonic-gate { 880*0Sstevel@tonic-gate /* make sure that we are not getting application data when we 881*0Sstevel@tonic-gate * are doing a handshake for the first time */ 882*0Sstevel@tonic-gate if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && 883*0Sstevel@tonic-gate (s->enc_read_ctx == NULL)) 884*0Sstevel@tonic-gate { 885*0Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE; 886*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE); 887*0Sstevel@tonic-gate goto f_err; 888*0Sstevel@tonic-gate } 889*0Sstevel@tonic-gate 890*0Sstevel@tonic-gate if (len <= 0) return(len); 891*0Sstevel@tonic-gate 892*0Sstevel@tonic-gate if ((unsigned int)len > rr->length) 893*0Sstevel@tonic-gate n = rr->length; 894*0Sstevel@tonic-gate else 895*0Sstevel@tonic-gate n = (unsigned int)len; 896*0Sstevel@tonic-gate 897*0Sstevel@tonic-gate memcpy(buf,&(rr->data[rr->off]),n); 898*0Sstevel@tonic-gate if (!peek) 899*0Sstevel@tonic-gate { 900*0Sstevel@tonic-gate rr->length-=n; 901*0Sstevel@tonic-gate rr->off+=n; 902*0Sstevel@tonic-gate if (rr->length == 0) 903*0Sstevel@tonic-gate { 904*0Sstevel@tonic-gate s->rstate=SSL_ST_READ_HEADER; 905*0Sstevel@tonic-gate rr->off=0; 906*0Sstevel@tonic-gate } 907*0Sstevel@tonic-gate } 908*0Sstevel@tonic-gate return(n); 909*0Sstevel@tonic-gate } 910*0Sstevel@tonic-gate 911*0Sstevel@tonic-gate 912*0Sstevel@tonic-gate /* If we get here, then type != rr->type; if we have a handshake 913*0Sstevel@tonic-gate * message, then it was unexpected (Hello Request or Client Hello). */ 914*0Sstevel@tonic-gate 915*0Sstevel@tonic-gate /* In case of record types for which we have 'fragment' storage, 916*0Sstevel@tonic-gate * fill that so that we can process the data at a fixed place. 917*0Sstevel@tonic-gate */ 918*0Sstevel@tonic-gate { 919*0Sstevel@tonic-gate unsigned int dest_maxlen = 0; 920*0Sstevel@tonic-gate unsigned char *dest = NULL; 921*0Sstevel@tonic-gate unsigned int *dest_len = NULL; 922*0Sstevel@tonic-gate 923*0Sstevel@tonic-gate if (rr->type == SSL3_RT_HANDSHAKE) 924*0Sstevel@tonic-gate { 925*0Sstevel@tonic-gate dest_maxlen = sizeof s->s3->handshake_fragment; 926*0Sstevel@tonic-gate dest = s->s3->handshake_fragment; 927*0Sstevel@tonic-gate dest_len = &s->s3->handshake_fragment_len; 928*0Sstevel@tonic-gate } 929*0Sstevel@tonic-gate else if (rr->type == SSL3_RT_ALERT) 930*0Sstevel@tonic-gate { 931*0Sstevel@tonic-gate dest_maxlen = sizeof s->s3->alert_fragment; 932*0Sstevel@tonic-gate dest = s->s3->alert_fragment; 933*0Sstevel@tonic-gate dest_len = &s->s3->alert_fragment_len; 934*0Sstevel@tonic-gate } 935*0Sstevel@tonic-gate 936*0Sstevel@tonic-gate if (dest_maxlen > 0) 937*0Sstevel@tonic-gate { 938*0Sstevel@tonic-gate n = dest_maxlen - *dest_len; /* available space in 'dest' */ 939*0Sstevel@tonic-gate if (rr->length < n) 940*0Sstevel@tonic-gate n = rr->length; /* available bytes */ 941*0Sstevel@tonic-gate 942*0Sstevel@tonic-gate /* now move 'n' bytes: */ 943*0Sstevel@tonic-gate while (n-- > 0) 944*0Sstevel@tonic-gate { 945*0Sstevel@tonic-gate dest[(*dest_len)++] = rr->data[rr->off++]; 946*0Sstevel@tonic-gate rr->length--; 947*0Sstevel@tonic-gate } 948*0Sstevel@tonic-gate 949*0Sstevel@tonic-gate if (*dest_len < dest_maxlen) 950*0Sstevel@tonic-gate goto start; /* fragment was too small */ 951*0Sstevel@tonic-gate } 952*0Sstevel@tonic-gate } 953*0Sstevel@tonic-gate 954*0Sstevel@tonic-gate /* s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; 955*0Sstevel@tonic-gate * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. 956*0Sstevel@tonic-gate * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ 957*0Sstevel@tonic-gate 958*0Sstevel@tonic-gate /* If we are a client, check for an incoming 'Hello Request': */ 959*0Sstevel@tonic-gate if ((!s->server) && 960*0Sstevel@tonic-gate (s->s3->handshake_fragment_len >= 4) && 961*0Sstevel@tonic-gate (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && 962*0Sstevel@tonic-gate (s->session != NULL) && (s->session->cipher != NULL)) 963*0Sstevel@tonic-gate { 964*0Sstevel@tonic-gate s->s3->handshake_fragment_len = 0; 965*0Sstevel@tonic-gate 966*0Sstevel@tonic-gate if ((s->s3->handshake_fragment[1] != 0) || 967*0Sstevel@tonic-gate (s->s3->handshake_fragment[2] != 0) || 968*0Sstevel@tonic-gate (s->s3->handshake_fragment[3] != 0)) 969*0Sstevel@tonic-gate { 970*0Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 971*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_HELLO_REQUEST); 972*0Sstevel@tonic-gate goto err; 973*0Sstevel@tonic-gate } 974*0Sstevel@tonic-gate 975*0Sstevel@tonic-gate if (s->msg_callback) 976*0Sstevel@tonic-gate s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg); 977*0Sstevel@tonic-gate 978*0Sstevel@tonic-gate if (SSL_is_init_finished(s) && 979*0Sstevel@tonic-gate !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && 980*0Sstevel@tonic-gate !s->s3->renegotiate) 981*0Sstevel@tonic-gate { 982*0Sstevel@tonic-gate ssl3_renegotiate(s); 983*0Sstevel@tonic-gate if (ssl3_renegotiate_check(s)) 984*0Sstevel@tonic-gate { 985*0Sstevel@tonic-gate i=s->handshake_func(s); 986*0Sstevel@tonic-gate if (i < 0) return(i); 987*0Sstevel@tonic-gate if (i == 0) 988*0Sstevel@tonic-gate { 989*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); 990*0Sstevel@tonic-gate return(-1); 991*0Sstevel@tonic-gate } 992*0Sstevel@tonic-gate 993*0Sstevel@tonic-gate if (!(s->mode & SSL_MODE_AUTO_RETRY)) 994*0Sstevel@tonic-gate { 995*0Sstevel@tonic-gate if (s->s3->rbuf.left == 0) /* no read-ahead left? */ 996*0Sstevel@tonic-gate { 997*0Sstevel@tonic-gate BIO *bio; 998*0Sstevel@tonic-gate /* In the case where we try to read application data, 999*0Sstevel@tonic-gate * but we trigger an SSL handshake, we return -1 with 1000*0Sstevel@tonic-gate * the retry option set. Otherwise renegotiation may 1001*0Sstevel@tonic-gate * cause nasty problems in the blocking world */ 1002*0Sstevel@tonic-gate s->rwstate=SSL_READING; 1003*0Sstevel@tonic-gate bio=SSL_get_rbio(s); 1004*0Sstevel@tonic-gate BIO_clear_retry_flags(bio); 1005*0Sstevel@tonic-gate BIO_set_retry_read(bio); 1006*0Sstevel@tonic-gate return(-1); 1007*0Sstevel@tonic-gate } 1008*0Sstevel@tonic-gate } 1009*0Sstevel@tonic-gate } 1010*0Sstevel@tonic-gate } 1011*0Sstevel@tonic-gate /* we either finished a handshake or ignored the request, 1012*0Sstevel@tonic-gate * now try again to obtain the (application) data we were asked for */ 1013*0Sstevel@tonic-gate goto start; 1014*0Sstevel@tonic-gate } 1015*0Sstevel@tonic-gate 1016*0Sstevel@tonic-gate if (s->s3->alert_fragment_len >= 2) 1017*0Sstevel@tonic-gate { 1018*0Sstevel@tonic-gate int alert_level = s->s3->alert_fragment[0]; 1019*0Sstevel@tonic-gate int alert_descr = s->s3->alert_fragment[1]; 1020*0Sstevel@tonic-gate 1021*0Sstevel@tonic-gate s->s3->alert_fragment_len = 0; 1022*0Sstevel@tonic-gate 1023*0Sstevel@tonic-gate if (s->msg_callback) 1024*0Sstevel@tonic-gate s->msg_callback(0, s->version, SSL3_RT_ALERT, s->s3->alert_fragment, 2, s, s->msg_callback_arg); 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate if (s->info_callback != NULL) 1027*0Sstevel@tonic-gate cb=s->info_callback; 1028*0Sstevel@tonic-gate else if (s->ctx->info_callback != NULL) 1029*0Sstevel@tonic-gate cb=s->ctx->info_callback; 1030*0Sstevel@tonic-gate 1031*0Sstevel@tonic-gate if (cb != NULL) 1032*0Sstevel@tonic-gate { 1033*0Sstevel@tonic-gate j = (alert_level << 8) | alert_descr; 1034*0Sstevel@tonic-gate cb(s, SSL_CB_READ_ALERT, j); 1035*0Sstevel@tonic-gate } 1036*0Sstevel@tonic-gate 1037*0Sstevel@tonic-gate if (alert_level == 1) /* warning */ 1038*0Sstevel@tonic-gate { 1039*0Sstevel@tonic-gate s->s3->warn_alert = alert_descr; 1040*0Sstevel@tonic-gate if (alert_descr == SSL_AD_CLOSE_NOTIFY) 1041*0Sstevel@tonic-gate { 1042*0Sstevel@tonic-gate s->shutdown |= SSL_RECEIVED_SHUTDOWN; 1043*0Sstevel@tonic-gate return(0); 1044*0Sstevel@tonic-gate } 1045*0Sstevel@tonic-gate } 1046*0Sstevel@tonic-gate else if (alert_level == 2) /* fatal */ 1047*0Sstevel@tonic-gate { 1048*0Sstevel@tonic-gate char tmp[16]; 1049*0Sstevel@tonic-gate 1050*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 1051*0Sstevel@tonic-gate s->s3->fatal_alert = alert_descr; 1052*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); 1053*0Sstevel@tonic-gate BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr); 1054*0Sstevel@tonic-gate ERR_add_error_data(2,"SSL alert number ",tmp); 1055*0Sstevel@tonic-gate s->shutdown|=SSL_RECEIVED_SHUTDOWN; 1056*0Sstevel@tonic-gate SSL_CTX_remove_session(s->ctx,s->session); 1057*0Sstevel@tonic-gate return(0); 1058*0Sstevel@tonic-gate } 1059*0Sstevel@tonic-gate else 1060*0Sstevel@tonic-gate { 1061*0Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER; 1062*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE); 1063*0Sstevel@tonic-gate goto f_err; 1064*0Sstevel@tonic-gate } 1065*0Sstevel@tonic-gate 1066*0Sstevel@tonic-gate goto start; 1067*0Sstevel@tonic-gate } 1068*0Sstevel@tonic-gate 1069*0Sstevel@tonic-gate if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */ 1070*0Sstevel@tonic-gate { 1071*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 1072*0Sstevel@tonic-gate rr->length=0; 1073*0Sstevel@tonic-gate return(0); 1074*0Sstevel@tonic-gate } 1075*0Sstevel@tonic-gate 1076*0Sstevel@tonic-gate if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) 1077*0Sstevel@tonic-gate { 1078*0Sstevel@tonic-gate /* 'Change Cipher Spec' is just a single byte, so we know 1079*0Sstevel@tonic-gate * exactly what the record payload has to look like */ 1080*0Sstevel@tonic-gate if ( (rr->length != 1) || (rr->off != 0) || 1081*0Sstevel@tonic-gate (rr->data[0] != SSL3_MT_CCS)) 1082*0Sstevel@tonic-gate { 1083*0Sstevel@tonic-gate i=SSL_AD_ILLEGAL_PARAMETER; 1084*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); 1085*0Sstevel@tonic-gate goto err; 1086*0Sstevel@tonic-gate } 1087*0Sstevel@tonic-gate 1088*0Sstevel@tonic-gate /* Check we have a cipher to change to */ 1089*0Sstevel@tonic-gate if (s->s3->tmp.new_cipher == NULL) 1090*0Sstevel@tonic-gate { 1091*0Sstevel@tonic-gate i=SSL_AD_UNEXPECTED_MESSAGE; 1092*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_CCS_RECEIVED_EARLY); 1093*0Sstevel@tonic-gate goto err; 1094*0Sstevel@tonic-gate } 1095*0Sstevel@tonic-gate 1096*0Sstevel@tonic-gate rr->length=0; 1097*0Sstevel@tonic-gate 1098*0Sstevel@tonic-gate if (s->msg_callback) 1099*0Sstevel@tonic-gate s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, s->msg_callback_arg); 1100*0Sstevel@tonic-gate 1101*0Sstevel@tonic-gate s->s3->change_cipher_spec=1; 1102*0Sstevel@tonic-gate if (!do_change_cipher_spec(s)) 1103*0Sstevel@tonic-gate goto err; 1104*0Sstevel@tonic-gate else 1105*0Sstevel@tonic-gate goto start; 1106*0Sstevel@tonic-gate } 1107*0Sstevel@tonic-gate 1108*0Sstevel@tonic-gate /* Unexpected handshake message (Client Hello, or protocol violation) */ 1109*0Sstevel@tonic-gate if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) 1110*0Sstevel@tonic-gate { 1111*0Sstevel@tonic-gate if (((s->state&SSL_ST_MASK) == SSL_ST_OK) && 1112*0Sstevel@tonic-gate !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) 1113*0Sstevel@tonic-gate { 1114*0Sstevel@tonic-gate #if 0 /* worked only because C operator preferences are not as expected (and 1115*0Sstevel@tonic-gate * because this is not really needed for clients except for detecting 1116*0Sstevel@tonic-gate * protocol violations): */ 1117*0Sstevel@tonic-gate s->state=SSL_ST_BEFORE|(s->server) 1118*0Sstevel@tonic-gate ?SSL_ST_ACCEPT 1119*0Sstevel@tonic-gate :SSL_ST_CONNECT; 1120*0Sstevel@tonic-gate #else 1121*0Sstevel@tonic-gate s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; 1122*0Sstevel@tonic-gate #endif 1123*0Sstevel@tonic-gate s->new_session=1; 1124*0Sstevel@tonic-gate } 1125*0Sstevel@tonic-gate i=s->handshake_func(s); 1126*0Sstevel@tonic-gate if (i < 0) return(i); 1127*0Sstevel@tonic-gate if (i == 0) 1128*0Sstevel@tonic-gate { 1129*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); 1130*0Sstevel@tonic-gate return(-1); 1131*0Sstevel@tonic-gate } 1132*0Sstevel@tonic-gate 1133*0Sstevel@tonic-gate if (!(s->mode & SSL_MODE_AUTO_RETRY)) 1134*0Sstevel@tonic-gate { 1135*0Sstevel@tonic-gate if (s->s3->rbuf.left == 0) /* no read-ahead left? */ 1136*0Sstevel@tonic-gate { 1137*0Sstevel@tonic-gate BIO *bio; 1138*0Sstevel@tonic-gate /* In the case where we try to read application data, 1139*0Sstevel@tonic-gate * but we trigger an SSL handshake, we return -1 with 1140*0Sstevel@tonic-gate * the retry option set. Otherwise renegotiation may 1141*0Sstevel@tonic-gate * cause nasty problems in the blocking world */ 1142*0Sstevel@tonic-gate s->rwstate=SSL_READING; 1143*0Sstevel@tonic-gate bio=SSL_get_rbio(s); 1144*0Sstevel@tonic-gate BIO_clear_retry_flags(bio); 1145*0Sstevel@tonic-gate BIO_set_retry_read(bio); 1146*0Sstevel@tonic-gate return(-1); 1147*0Sstevel@tonic-gate } 1148*0Sstevel@tonic-gate } 1149*0Sstevel@tonic-gate goto start; 1150*0Sstevel@tonic-gate } 1151*0Sstevel@tonic-gate 1152*0Sstevel@tonic-gate switch (rr->type) 1153*0Sstevel@tonic-gate { 1154*0Sstevel@tonic-gate default: 1155*0Sstevel@tonic-gate #ifndef OPENSSL_NO_TLS 1156*0Sstevel@tonic-gate /* TLS just ignores unknown message types */ 1157*0Sstevel@tonic-gate if (s->version == TLS1_VERSION) 1158*0Sstevel@tonic-gate { 1159*0Sstevel@tonic-gate rr->length = 0; 1160*0Sstevel@tonic-gate goto start; 1161*0Sstevel@tonic-gate } 1162*0Sstevel@tonic-gate #endif 1163*0Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE; 1164*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD); 1165*0Sstevel@tonic-gate goto f_err; 1166*0Sstevel@tonic-gate case SSL3_RT_CHANGE_CIPHER_SPEC: 1167*0Sstevel@tonic-gate case SSL3_RT_ALERT: 1168*0Sstevel@tonic-gate case SSL3_RT_HANDSHAKE: 1169*0Sstevel@tonic-gate /* we already handled all of these, with the possible exception 1170*0Sstevel@tonic-gate * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that 1171*0Sstevel@tonic-gate * should not happen when type != rr->type */ 1172*0Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE; 1173*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,ERR_R_INTERNAL_ERROR); 1174*0Sstevel@tonic-gate goto f_err; 1175*0Sstevel@tonic-gate case SSL3_RT_APPLICATION_DATA: 1176*0Sstevel@tonic-gate /* At this point, we were expecting handshake data, 1177*0Sstevel@tonic-gate * but have application data. If the library was 1178*0Sstevel@tonic-gate * running inside ssl3_read() (i.e. in_read_app_data 1179*0Sstevel@tonic-gate * is set) and it makes sense to read application data 1180*0Sstevel@tonic-gate * at this point (session renegotiation not yet started), 1181*0Sstevel@tonic-gate * we will indulge it. 1182*0Sstevel@tonic-gate */ 1183*0Sstevel@tonic-gate if (s->s3->in_read_app_data && 1184*0Sstevel@tonic-gate (s->s3->total_renegotiations != 0) && 1185*0Sstevel@tonic-gate (( 1186*0Sstevel@tonic-gate (s->state & SSL_ST_CONNECT) && 1187*0Sstevel@tonic-gate (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && 1188*0Sstevel@tonic-gate (s->state <= SSL3_ST_CR_SRVR_HELLO_A) 1189*0Sstevel@tonic-gate ) || ( 1190*0Sstevel@tonic-gate (s->state & SSL_ST_ACCEPT) && 1191*0Sstevel@tonic-gate (s->state <= SSL3_ST_SW_HELLO_REQ_A) && 1192*0Sstevel@tonic-gate (s->state >= SSL3_ST_SR_CLNT_HELLO_A) 1193*0Sstevel@tonic-gate ) 1194*0Sstevel@tonic-gate )) 1195*0Sstevel@tonic-gate { 1196*0Sstevel@tonic-gate s->s3->in_read_app_data=2; 1197*0Sstevel@tonic-gate return(-1); 1198*0Sstevel@tonic-gate } 1199*0Sstevel@tonic-gate else 1200*0Sstevel@tonic-gate { 1201*0Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE; 1202*0Sstevel@tonic-gate SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD); 1203*0Sstevel@tonic-gate goto f_err; 1204*0Sstevel@tonic-gate } 1205*0Sstevel@tonic-gate } 1206*0Sstevel@tonic-gate /* not reached */ 1207*0Sstevel@tonic-gate 1208*0Sstevel@tonic-gate f_err: 1209*0Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,al); 1210*0Sstevel@tonic-gate err: 1211*0Sstevel@tonic-gate return(-1); 1212*0Sstevel@tonic-gate } 1213*0Sstevel@tonic-gate 1214*0Sstevel@tonic-gate static int do_change_cipher_spec(SSL *s) 1215*0Sstevel@tonic-gate { 1216*0Sstevel@tonic-gate int i; 1217*0Sstevel@tonic-gate const char *sender; 1218*0Sstevel@tonic-gate int slen; 1219*0Sstevel@tonic-gate 1220*0Sstevel@tonic-gate if (s->state & SSL_ST_ACCEPT) 1221*0Sstevel@tonic-gate i=SSL3_CHANGE_CIPHER_SERVER_READ; 1222*0Sstevel@tonic-gate else 1223*0Sstevel@tonic-gate i=SSL3_CHANGE_CIPHER_CLIENT_READ; 1224*0Sstevel@tonic-gate 1225*0Sstevel@tonic-gate if (s->s3->tmp.key_block == NULL) 1226*0Sstevel@tonic-gate { 1227*0Sstevel@tonic-gate s->session->cipher=s->s3->tmp.new_cipher; 1228*0Sstevel@tonic-gate if (!s->method->ssl3_enc->setup_key_block(s)) return(0); 1229*0Sstevel@tonic-gate } 1230*0Sstevel@tonic-gate 1231*0Sstevel@tonic-gate if (!s->method->ssl3_enc->change_cipher_state(s,i)) 1232*0Sstevel@tonic-gate return(0); 1233*0Sstevel@tonic-gate 1234*0Sstevel@tonic-gate /* we have to record the message digest at 1235*0Sstevel@tonic-gate * this point so we can get it before we read 1236*0Sstevel@tonic-gate * the finished message */ 1237*0Sstevel@tonic-gate if (s->state & SSL_ST_CONNECT) 1238*0Sstevel@tonic-gate { 1239*0Sstevel@tonic-gate sender=s->method->ssl3_enc->server_finished_label; 1240*0Sstevel@tonic-gate slen=s->method->ssl3_enc->server_finished_label_len; 1241*0Sstevel@tonic-gate } 1242*0Sstevel@tonic-gate else 1243*0Sstevel@tonic-gate { 1244*0Sstevel@tonic-gate sender=s->method->ssl3_enc->client_finished_label; 1245*0Sstevel@tonic-gate slen=s->method->ssl3_enc->client_finished_label_len; 1246*0Sstevel@tonic-gate } 1247*0Sstevel@tonic-gate 1248*0Sstevel@tonic-gate s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, 1249*0Sstevel@tonic-gate &(s->s3->finish_dgst1), 1250*0Sstevel@tonic-gate &(s->s3->finish_dgst2), 1251*0Sstevel@tonic-gate sender,slen,s->s3->tmp.peer_finish_md); 1252*0Sstevel@tonic-gate 1253*0Sstevel@tonic-gate return(1); 1254*0Sstevel@tonic-gate } 1255*0Sstevel@tonic-gate 1256*0Sstevel@tonic-gate void ssl3_send_alert(SSL *s, int level, int desc) 1257*0Sstevel@tonic-gate { 1258*0Sstevel@tonic-gate /* Map tls/ssl alert value to correct one */ 1259*0Sstevel@tonic-gate desc=s->method->ssl3_enc->alert_value(desc); 1260*0Sstevel@tonic-gate if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) 1261*0Sstevel@tonic-gate desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have protocol_version alerts */ 1262*0Sstevel@tonic-gate if (desc < 0) return; 1263*0Sstevel@tonic-gate /* If a fatal one, remove from cache */ 1264*0Sstevel@tonic-gate if ((level == 2) && (s->session != NULL)) 1265*0Sstevel@tonic-gate SSL_CTX_remove_session(s->ctx,s->session); 1266*0Sstevel@tonic-gate 1267*0Sstevel@tonic-gate s->s3->alert_dispatch=1; 1268*0Sstevel@tonic-gate s->s3->send_alert[0]=level; 1269*0Sstevel@tonic-gate s->s3->send_alert[1]=desc; 1270*0Sstevel@tonic-gate if (s->s3->wbuf.left == 0) /* data still being written out? */ 1271*0Sstevel@tonic-gate ssl3_dispatch_alert(s); 1272*0Sstevel@tonic-gate /* else data is still being written out, we will get written 1273*0Sstevel@tonic-gate * some time in the future */ 1274*0Sstevel@tonic-gate } 1275*0Sstevel@tonic-gate 1276*0Sstevel@tonic-gate int ssl3_dispatch_alert(SSL *s) 1277*0Sstevel@tonic-gate { 1278*0Sstevel@tonic-gate int i,j; 1279*0Sstevel@tonic-gate void (*cb)(const SSL *ssl,int type,int val)=NULL; 1280*0Sstevel@tonic-gate 1281*0Sstevel@tonic-gate s->s3->alert_dispatch=0; 1282*0Sstevel@tonic-gate i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0); 1283*0Sstevel@tonic-gate if (i <= 0) 1284*0Sstevel@tonic-gate { 1285*0Sstevel@tonic-gate s->s3->alert_dispatch=1; 1286*0Sstevel@tonic-gate } 1287*0Sstevel@tonic-gate else 1288*0Sstevel@tonic-gate { 1289*0Sstevel@tonic-gate /* Alert sent to BIO. If it is important, flush it now. 1290*0Sstevel@tonic-gate * If the message does not get sent due to non-blocking IO, 1291*0Sstevel@tonic-gate * we will not worry too much. */ 1292*0Sstevel@tonic-gate if (s->s3->send_alert[0] == SSL3_AL_FATAL) 1293*0Sstevel@tonic-gate (void)BIO_flush(s->wbio); 1294*0Sstevel@tonic-gate 1295*0Sstevel@tonic-gate if (s->msg_callback) 1296*0Sstevel@tonic-gate s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s, s->msg_callback_arg); 1297*0Sstevel@tonic-gate 1298*0Sstevel@tonic-gate if (s->info_callback != NULL) 1299*0Sstevel@tonic-gate cb=s->info_callback; 1300*0Sstevel@tonic-gate else if (s->ctx->info_callback != NULL) 1301*0Sstevel@tonic-gate cb=s->ctx->info_callback; 1302*0Sstevel@tonic-gate 1303*0Sstevel@tonic-gate if (cb != NULL) 1304*0Sstevel@tonic-gate { 1305*0Sstevel@tonic-gate j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1]; 1306*0Sstevel@tonic-gate cb(s,SSL_CB_WRITE_ALERT,j); 1307*0Sstevel@tonic-gate } 1308*0Sstevel@tonic-gate } 1309*0Sstevel@tonic-gate return(i); 1310*0Sstevel@tonic-gate } 1311