(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/ssl/s3_pkt.c

    1: /* ssl/s3_pkt.c */
    2: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
    3:  * All rights reserved.
    4:  *
    5:  * This package is an SSL implementation written
    6:  * by Eric Young (eay@cryptsoft.com).
    7:  * The implementation was written so as to conform with Netscapes SSL.
    8:  * 
    9:  * This library is free for commercial and non-commercial use as long as
   10:  * the following conditions are aheared to.  The following conditions
   11:  * apply to all code found in this distribution, be it the RC4, RSA,
   12:  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
   13:  * included with this distribution is covered by the same copyright terms
   14:  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
   15:  * 
   16:  * Copyright remains Eric Young's, and as such any Copyright notices in
   17:  * the code are not to be removed.
   18:  * If this package is used in a product, Eric Young should be given attribution
   19:  * as the author of the parts of the library used.
   20:  * This can be in the form of a textual message at program startup or
   21:  * in documentation (online or textual) provided with the package.
   22:  * 
   23:  * Redistribution and use in source and binary forms, with or without
   24:  * modification, are permitted provided that the following conditions
   25:  * are met:
   26:  * 1. Redistributions of source code must retain the copyright
   27:  *    notice, this list of conditions and the following disclaimer.
   28:  * 2. Redistributions in binary form must reproduce the above copyright
   29:  *    notice, this list of conditions and the following disclaimer in the
   30:  *    documentation and/or other materials provided with the distribution.
   31:  * 3. All advertising materials mentioning features or use of this software
   32:  *    must display the following acknowledgement:
   33:  *    "This product includes cryptographic software written by
   34:  *     Eric Young (eay@cryptsoft.com)"
   35:  *    The word 'cryptographic' can be left out if the rouines from the library
   36:  *    being used are not cryptographic related :-).
   37:  * 4. If you include any Windows specific code (or a derivative thereof) from 
   38:  *    the apps directory (application code) you must include an acknowledgement:
   39:  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
   40:  * 
   41:  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
   42:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   43:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   44:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   45:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   46:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   47:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   48:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   49:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   50:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   51:  * SUCH DAMAGE.
   52:  * 
   53:  * The licence and distribution terms for any publically available version or
   54:  * derivative of this code cannot be changed.  i.e. this code cannot simply be
   55:  * copied and put under another distribution licence
   56:  * [including the GNU Public Licence.]
   57:  */
   58: /* ====================================================================
   59:  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
   60:  *
   61:  * Redistribution and use in source and binary forms, with or without
   62:  * modification, are permitted provided that the following conditions
   63:  * are met:
   64:  *
   65:  * 1. Redistributions of source code must retain the above copyright
   66:  *    notice, this list of conditions and the following disclaimer. 
   67:  *
   68:  * 2. Redistributions in binary form must reproduce the above copyright
   69:  *    notice, this list of conditions and the following disclaimer in
   70:  *    the documentation and/or other materials provided with the
   71:  *    distribution.
   72:  *
   73:  * 3. All advertising materials mentioning features or use of this
   74:  *    software must display the following acknowledgment:
   75:  *    "This product includes software developed by the OpenSSL Project
   76:  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
   77:  *
   78:  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
   79:  *    endorse or promote products derived from this software without
   80:  *    prior written permission. For written permission, please contact
   81:  *    openssl-core@openssl.org.
   82:  *
   83:  * 5. Products derived from this software may not be called "OpenSSL"
   84:  *    nor may "OpenSSL" appear in their names without prior written
   85:  *    permission of the OpenSSL Project.
   86:  *
   87:  * 6. Redistributions of any form whatsoever must retain the following
   88:  *    acknowledgment:
   89:  *    "This product includes software developed by the OpenSSL Project
   90:  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
   91:  *
   92:  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
   93:  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   94:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   95:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
   96:  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   97:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   98:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   99:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  100:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  101:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  102:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  103:  * OF THE POSSIBILITY OF SUCH DAMAGE.
  104:  * ====================================================================
  105:  *
  106:  * This product includes cryptographic software written by Eric Young
  107:  * (eay@cryptsoft.com).  This product includes software written by Tim
  108:  * Hudson (tjh@cryptsoft.com).
  109:  *
  110:  */
  111: 
  112: #include <stdio.h>
  113: #include <errno.h>
  114: #define USE_SOCKETS
  115: #include "ssl_locl.h"
  116: #include <openssl/evp.h>
  117: #include <openssl/buffer.h>
  118: 
  119: static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
  120:                          unsigned int len, int create_empty_fragment);
  121: static int ssl3_get_record(SSL *s);
  122: 
  123: int ssl3_read_n(SSL *s, int n, int max, int extend)
  124:         {
  125:         /* If extend == 0, obtain new n-byte packet; if extend == 1, increase
  126:          * packet by another n bytes.
  127:          * The packet will be in the sub-array of s->s3->rbuf.buf specified
  128:          * by s->packet and s->packet_length.
  129:          * (If s->read_ahead is set, 'max' bytes may be stored in rbuf
  130:          * [plus s->packet_length bytes if extend == 1].)
  131:          */
  132:         int i,off,newb;
  133: 
  134:         if (!extend)
  135:                 {
  136:                 /* start with empty packet ... */
  137:                 if (s->s3->rbuf.left == 0)
  138:                         s->s3->rbuf.offset = 0;
  139:                 s->packet = s->s3->rbuf.buf + s->s3->rbuf.offset;
  140:                 s->packet_length = 0;
  141:                 /* ... now we can act as if 'extend' was set */
  142:                 }
  143: 
  144:         /* extend reads should not span multiple packets for DTLS */
  145:         if ( SSL_version(s) == DTLS1_VERSION &&
  146:                 extend)
  147:                 {
  148:                 if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left)
  149:                         n = s->s3->rbuf.left;
  150:                 }
  151: 
  152:         /* if there is enough in the buffer from a previous read, take some */
  153:         if (s->s3->rbuf.left >= (int)n)
  154:                 {
  155:                 s->packet_length+=n;
  156:                 s->s3->rbuf.left-=n;
  157:                 s->s3->rbuf.offset+=n;
  158:                 return(n);
  159:                 }
  160: 
  161:         /* else we need to read more data */
  162:         if (!s->read_ahead)
  163:                 max=n;
  164: 
  165:         {
  166:                 /* avoid buffer overflow */
  167:                 int max_max = s->s3->rbuf.len - s->packet_length;
  168:                 if (max > max_max)
  169:                         max = max_max;
  170:         }
  171:         if (n > max) /* does not happen */
  172:                 {
  173:                 SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR);
  174:                 return -1;
  175:                 }
  176: 
  177:         off = s->packet_length;
  178:         newb = s->s3->rbuf.left;
  179:         /* Move any available bytes to front of buffer:
  180:          * 'off' bytes already pointed to by 'packet',
  181:          * 'newb' extra ones at the end */
  182:         if (s->packet != s->s3->rbuf.buf)
  183:                 {
  184:                 /*  off > 0 */
  185:                 memmove(s->s3->rbuf.buf, s->packet, off+newb);
  186:                 s->packet = s->s3->rbuf.buf;
  187:                 }
  188: 
  189:         while (newb < n)
  190:                 {
  191:                 /* Now we have off+newb bytes at the front of s->s3->rbuf.buf and need
  192:                  * to read in more until we have off+n (up to off+max if possible) */
  193: 
  194:                 clear_sys_error();
  195:                 if (s->rbio != NULL)
  196:                         {
  197:                         s->rwstate=SSL_READING;
  198:                         i=BIO_read(s->rbio,  &(s->s3->rbuf.buf[off+newb]), max-newb);
  199:                         }
  200:                 else
  201:                         {
  202:                         SSLerr(SSL_F_SSL3_READ_N,SSL_R_READ_BIO_NOT_SET);
  203:                         i = -1;
  204:                         }
  205: 
  206:                 if (i <= 0)
  207:                         {
  208:                         s->s3->rbuf.left = newb;
  209:                         return(i);
  210:                         }
  211:                 newb+=i;
  212:                 }
  213: 
  214:         /* done reading, now the book-keeping */
  215:         s->s3->rbuf.offset = off + n;
  216:         s->s3->rbuf.left = newb - n;
  217:         s->packet_length += n;
  218:         s->rwstate=SSL_NOTHING;
  219:         return(n);
  220:         }
  221: 
  222: /* Call this to get a new input record.
  223:  * It will return <= 0 if more data is needed, normally due to an error
  224:  * or non-blocking IO.
  225:  * When it finishes, one packet has been decoded and can be found in
  226:  * ssl->s3->rrec.type    - is the type of record
  227:  * ssl->s3->rrec.data,   - data
  228:  * ssl->s3->rrec.length, - number of bytes
  229:  */
  230: /* used only by ssl3_read_bytes */
  231: static int ssl3_get_record(SSL *s)
  232:         {
  233:         int ssl_major,ssl_minor,al;
  234:         int enc_err,n,i,ret= -1;
  235:         SSL3_RECORD *rr;
  236:         SSL_SESSION *sess;
  237:         unsigned char *p;
  238:         unsigned char md[EVP_MAX_MD_SIZE];
  239:         short version;
  240:         unsigned int mac_size;
  241:         int clear=0;
  242:         size_t extra;
  243:         int decryption_failed_or_bad_record_mac = 0;
  244:         unsigned char *mac = NULL;
  245: 
  246:         rr= &(s->s3->rrec);
  247:         sess=s->session;
  248: 
  249:         if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
  250:                 extra=SSL3_RT_MAX_EXTRA;
  251:         else
  252:                 extra=0;
  253:         if (extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE)
  254:                 {
  255:                 /* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
  256:                  * set after ssl3_setup_buffers() was done */
  257:                 SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
  258:                 return -1;
  259:                 }
  260: 
  261: again:
  262:         /* check if we have the header */
  263:         if (   (s->rstate != SSL_ST_READ_BODY) ||
  264:                 (s->packet_length < SSL3_RT_HEADER_LENGTH)) 
  265:                 {
  266:                 n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
  267:                 if (n <= 0) return(n); /* error or non-blocking */
  268:                 s->rstate=SSL_ST_READ_BODY;
  269: 
  270:                 p=s->packet;
  271: 
  272:                 /* Pull apart the header into the SSL3_RECORD */
  273:                 rr->type= *(p++);
  274:                 ssl_major= *(p++);
  275:                 ssl_minor= *(p++);
  276:                 version=(ssl_major<<8)|ssl_minor;
  277:                 n2s(p,rr->length);
  278: 
  279:                 /* Lets check version */
  280:                 if (!s->first_packet)
  281:                         {
  282:                         if (version != s->version)
  283:                                 {
  284:                                 SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
  285:                                 /* Send back error using their
  286:                                  * version number :-) */
  287:                                 s->version=version;
  288:                                 al=SSL_AD_PROTOCOL_VERSION;
  289:                                 goto f_err;
  290:                                 }
  291:                         }
  292: 
  293:                 if ((version>>8) != SSL3_VERSION_MAJOR)
  294:                         {
  295:                         SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
  296:                         goto err;
  297:                         }
  298: 
  299:                 if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
  300:                         {
  301:                         al=SSL_AD_RECORD_OVERFLOW;
  302:                         SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
  303:                         goto f_err;
  304:                         }
  305: 
  306:                 /* now s->rstate == SSL_ST_READ_BODY */
  307:                 }
  308: 
  309:         /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
  310: 
  311:         if (rr->length > s->packet_length-SSL3_RT_HEADER_LENGTH)
  312:                 {
  313:                 /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
  314:                 i=rr->length;
  315:                 n=ssl3_read_n(s,i,i,1);
  316:                 if (n <= 0) return(n); /* error or non-blocking io */
  317:                 /* now n == rr->length,
  318:                  * and s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length */
  319:                 }
  320: 
  321:         s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
  322: 
  323:         /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
  324:          * and we have that many bytes in s->packet
  325:          */
  326:         rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]);
  327: 
  328:         /* ok, we can now read from 's->packet' data into 'rr'
  329:          * rr->input points at rr->length bytes, which
  330:          * need to be copied into rr->data by either
  331:          * the decryption or by the decompression
  332:          * When the data is 'copied' into the rr->data buffer,
  333:          * rr->input will be pointed at the new buffer */ 
  334: 
  335:         /* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
  336:          * rr->length bytes of encrypted compressed stuff. */
  337: 
  338:         /* check is not needed I believe */
  339:         if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
  340:                 {
  341:                 al=SSL_AD_RECORD_OVERFLOW;
  342:                 SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
  343:                 goto f_err;
  344:                 }
  345: 
  346:         /* decrypt in place in 'rr->input' */
  347:         rr->data=rr->input;
  348: 
  349:         enc_err = s->method->ssl3_enc->enc(s,0);
  350:         if (enc_err <= 0)
  351:                 {
  352:                 if (enc_err == 0)
  353:                         /* SSLerr() and ssl3_send_alert() have been called */
  354:                         goto err;
  355: 
  356:                 /* Otherwise enc_err == -1, which indicates bad padding
  357:                  * (rec->length has not been changed in this case).
  358:                  * To minimize information leaked via timing, we will perform
  359:                  * the MAC computation anyway. */
  360:                 decryption_failed_or_bad_record_mac = 1;
  361:                 }
  362: 
  363: #ifdef TLS_DEBUG
  364: printf("dec %d\n",rr->length);
  365: { unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
  366: printf("\n");
  367: #endif
  368: 
  369:         /* r->length is now the compressed data plus mac */
  370:         if (   (sess == NULL) ||
  371:                 (s->enc_read_ctx == NULL) ||
  372:                 (s->read_hash == NULL))
  373:                 clear=1;
  374: 
  375:         if (!clear)
  376:                 {
  377:                 mac_size=EVP_MD_size(s->read_hash);
  378: 
  379:                 if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
  380:                         {
  381: #if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
  382:                         al=SSL_AD_RECORD_OVERFLOW;
  383:                         SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
  384:                         goto f_err;
  385: #else
  386:                         decryption_failed_or_bad_record_mac = 1;
  387: #endif                  
  388:                         }
  389:                 /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
  390:                 if (rr->length >= mac_size)
  391:                         {
  392:                         rr->length -= mac_size;
  393:                         mac = &rr->data[rr->length];
  394:                         }
  395:                 else
  396:                         {
  397:                         /* record (minus padding) is too short to contain a MAC */
  398: #if 0 /* OK only for stream ciphers */
  399:                         al=SSL_AD_DECODE_ERROR;
  400:                         SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
  401:                         goto f_err;
  402: #else
  403:                         decryption_failed_or_bad_record_mac = 1;
  404:                         rr->length = 0;
  405: #endif
  406:                         }
  407:                 i=s->method->ssl3_enc->mac(s,md,0);
  408:                 if (mac == NULL || memcmp(md, mac, mac_size) != 0)
  409:                         {
  410:                         decryption_failed_or_bad_record_mac = 1;
  411:                         }
  412:                 }
  413: 
  414:         if (decryption_failed_or_bad_record_mac)
  415:                 {
  416:                 /* A separate 'decryption_failed' alert was introduced with TLS 1.0,
  417:                  * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
  418:                  * failure is directly visible from the ciphertext anyway,
  419:                  * we should not reveal which kind of error occured -- this
  420:                  * might become visible to an attacker (e.g. via a logfile) */
  421:                 al=SSL_AD_BAD_RECORD_MAC;
  422:                 SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
  423:                 goto f_err;
  424:                 }
  425: 
  426:         /* r->length is now just compressed */
  427:         if (s->expand != NULL)
  428:                 {
  429:                 if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra)
  430:                         {
  431:                         al=SSL_AD_RECORD_OVERFLOW;
  432:                         SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
  433:                         goto f_err;
  434:                         }
  435:                 if (!ssl3_do_uncompress(s))
  436:                         {
  437:                         al=SSL_AD_DECOMPRESSION_FAILURE;
  438:                         SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
  439:                         goto f_err;
  440:                         }
  441:                 }
  442: 
  443:         if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra)
  444:                 {
  445:                 al=SSL_AD_RECORD_OVERFLOW;
  446:                 SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
  447:                 goto f_err;
  448:                 }
  449: 
  450:         rr->off=0;
  451:         /* So at this point the following is true
  452:          * ssl->s3->rrec.type  is the type of record
  453:          * ssl->s3->rrec.length        == number of bytes in record
  454:          * ssl->s3->rrec.off   == offset to first valid byte
  455:          * ssl->s3->rrec.data  == where to take bytes from, increment
  456:          *                        after use :-).
  457:          */
  458: 
  459:         /* we have pulled in a full packet so zero things */
  460:         s->packet_length=0;
  461: 
  462:         /* just read a 0 length packet */
  463:         if (rr->length == 0) goto again;
  464: 
  465:         return(1);
  466: 
  467: f_err:
  468:         ssl3_send_alert(s,SSL3_AL_FATAL,al);
  469: err:
  470:         return(ret);
  471:         }
  472: 
  473: int ssl3_do_uncompress(SSL *ssl)
  474:         {
  475: #ifndef OPENSSL_NO_COMP
  476:         int i;
  477:         SSL3_RECORD *rr;
  478: 
  479:         rr= &(ssl->s3->rrec);
  480:         i=COMP_expand_block(ssl->expand,rr->comp,
  481:                 SSL3_RT_MAX_PLAIN_LENGTH,rr->data,(int)rr->length);
  482:         if (i < 0)
  483:                 return(0);
  484:         else
  485:                 rr->length=i;
  486:         rr->data=rr->comp;
  487: #endif
  488:         return(1);
  489:         }
  490: 
  491: int ssl3_do_compress(SSL *ssl)
  492:         {
  493: #ifndef OPENSSL_NO_COMP
  494:         int i;
  495:         SSL3_RECORD *wr;
  496: 
  497:         wr= &(ssl->s3->wrec);
  498:         i=COMP_compress_block(ssl->compress,wr->data,
  499:                 SSL3_RT_MAX_COMPRESSED_LENGTH,
  500:                 wr->input,(int)wr->length);
  501:         if (i < 0)
  502:                 return(0);
  503:         else
  504:                 wr->length=i;
  505: 
  506:         wr->input=wr->data;
  507: #endif
  508:         return(1);
  509:         }
  510: 
  511: /* Call this to write data in records of type 'type'
  512:  * It will return <= 0 if not all data has been sent or non-blocking IO.
  513:  */
  514: int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
  515:         {
  516:         const unsigned char *buf=buf_;
  517:         unsigned int tot,n,nw;
  518:         int i;
  519: 
  520:         s->rwstate=SSL_NOTHING;
  521:         tot=s->s3->wnum;
  522:         s->s3->wnum=0;
  523: 
  524:         if (SSL_in_init(s) && !s->in_handshake)
  525:                 {
  526:                 i=s->handshake_func(s);
  527:                 if (i < 0) return(i);
  528:                 if (i == 0)
  529:                         {
  530:                         SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
  531:                         return -1;
  532:                         }
  533:                 }
  534: 
  535:         n=(len-tot);
  536:         for (;;)
  537:                 {
  538:                 if (n > SSL3_RT_MAX_PLAIN_LENGTH)
  539:                         nw=SSL3_RT_MAX_PLAIN_LENGTH;
  540:                 else
  541:                         nw=n;
  542: 
  543:                 i=do_ssl3_write(s, type, &(buf[tot]), nw, 0);
  544:                 if (i <= 0)
  545:                         {
  546:                         s->s3->wnum=tot;
  547:                         return i;
  548:                         }
  549: 
  550:                 if ((i == (int)n) ||
  551:                         (type == SSL3_RT_APPLICATION_DATA &&
  552:                          (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))
  553:                         {
  554:                         /* next chunk of data should get another prepended empty fragment
  555:                          * in ciphersuites with known-IV weakness: */
  556:                         s->s3->empty_fragment_done = 0;
  557:                         
  558:                         return tot+i;
  559:                         }
  560: 
  561:                 n-=i;
  562:                 tot+=i;
  563:                 }
  564:         }
  565: 
  566: static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
  567:                          unsigned int len, int create_empty_fragment)
  568:         {
  569:         unsigned char *p,*plen;
  570:         int i,mac_size,clear=0;
  571:         int prefix_len = 0;
  572:         SSL3_RECORD *wr;
  573:         SSL3_BUFFER *wb;
  574:         SSL_SESSION *sess;
  575: 
  576:         /* first check if there is a SSL3_BUFFER still being written