s2_pkt.c revision 76870
155714Skris/* ssl/s2_pkt.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5772616Skris */ 5872616Skris/* ==================================================================== 5972616Skris * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 6055949Skris * 6172616Skris * Redistribution and use in source and binary forms, with or without 6272616Skris * modification, are permitted provided that the following conditions 6372616Skris * are met: 6472616Skris * 6572616Skris * 1. Redistributions of source code must retain the above copyright 6672616Skris * notice, this list of conditions and the following disclaimer. 6772616Skris * 6872616Skris * 2. Redistributions in binary form must reproduce the above copyright 6972616Skris * notice, this list of conditions and the following disclaimer in 7072616Skris * the documentation and/or other materials provided with the 7172616Skris * distribution. 7272616Skris * 7372616Skris * 3. All advertising materials mentioning features or use of this 7472616Skris * software must display the following acknowledgment: 7572616Skris * "This product includes software developed by the OpenSSL Project 7672616Skris * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 7772616Skris * 7872616Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 7972616Skris * endorse or promote products derived from this software without 8072616Skris * prior written permission. For written permission, please contact 8172616Skris * openssl-core@openssl.org. 8272616Skris * 8372616Skris * 5. Products derived from this software may not be called "OpenSSL" 8472616Skris * nor may "OpenSSL" appear in their names without prior written 8572616Skris * permission of the OpenSSL Project. 8672616Skris * 8772616Skris * 6. Redistributions of any form whatsoever must retain the following 8872616Skris * acknowledgment: 8972616Skris * "This product includes software developed by the OpenSSL Project 9072616Skris * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 9172616Skris * 9272616Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 9372616Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9472616Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 9572616Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 9672616Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 9772616Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 9872616Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 9972616Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10072616Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 10172616Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10272616Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 10372616Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 10472616Skris * ==================================================================== 10572616Skris * 10672616Skris * This product includes cryptographic software written by Eric Young 10772616Skris * (eay@cryptsoft.com). This product includes software written by Tim 10872616Skris * Hudson (tjh@cryptsoft.com). 10972616Skris * 11055949Skris * $FreeBSD: head/crypto/openssl/ssl/s2_pkt.c 76870 2001-05-20 03:17:35Z kris $ 11155714Skris */ 11255714Skris 11359194Skris#include "ssl_locl.h" 11455949Skris#ifndef NO_SSL2 11555714Skris#include <stdio.h> 11655714Skris#include <errno.h> 11755714Skris#define USE_SOCKETS 11855714Skris 11955714Skrisstatic int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend); 12055714Skrisstatic int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); 12155714Skrisstatic int write_pending(SSL *s, const unsigned char *buf, unsigned int len); 12255714Skrisstatic int ssl_mt_error(int n); 12355714Skris 12455714Skris 12572616Skris/* SSL 2.0 imlementation for SSL_read/SSL_peek - 12655714Skris * This routine will return 0 to len bytes, decrypted etc if required. 12755714Skris */ 12872616Skrisstatic int ssl2_read_internal(SSL *s, void *buf, int len, int peek) 12955714Skris { 13055714Skris int n; 13155714Skris unsigned char mac[MAX_MAC_SIZE]; 13255714Skris unsigned char *p; 13355714Skris int i; 13455714Skris unsigned int mac_size=0; 13555714Skris 13672616Skris ssl2_read_again: 13755714Skris if (SSL_in_init(s) && !s->in_handshake) 13855714Skris { 13955714Skris n=s->handshake_func(s); 14055714Skris if (n < 0) return(n); 14155714Skris if (n == 0) 14255714Skris { 14372616Skris SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_SSL_HANDSHAKE_FAILURE); 14455714Skris return(-1); 14555714Skris } 14655714Skris } 14755714Skris 14855714Skris clear_sys_error(); 14955714Skris s->rwstate=SSL_NOTHING; 15055714Skris if (len <= 0) return(len); 15155714Skris 15255714Skris if (s->s2->ract_data_length != 0) /* read from buffer */ 15355714Skris { 15455714Skris if (len > s->s2->ract_data_length) 15555714Skris n=s->s2->ract_data_length; 15655714Skris else 15755714Skris n=len; 15855714Skris 15955714Skris memcpy(buf,s->s2->ract_data,(unsigned int)n); 16072616Skris if (!peek) 16172616Skris { 16272616Skris s->s2->ract_data_length-=n; 16372616Skris s->s2->ract_data+=n; 16472616Skris if (s->s2->ract_data_length == 0) 16572616Skris s->rstate=SSL_ST_READ_HEADER; 16672616Skris } 16772616Skris 16855714Skris return(n); 16955714Skris } 17055714Skris 17172616Skris /* s->s2->ract_data_length == 0 17272616Skris * 17372616Skris * Fill the buffer, then goto ssl2_read_again. 17472616Skris */ 17572616Skris 17655714Skris if (s->rstate == SSL_ST_READ_HEADER) 17755714Skris { 17855714Skris if (s->first_packet) 17955714Skris { 18055714Skris n=read_n(s,5,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0); 18155714Skris if (n <= 0) return(n); /* error or non-blocking */ 18255714Skris s->first_packet=0; 18355714Skris p=s->packet; 18455714Skris if (!((p[0] & 0x80) && ( 18555714Skris (p[2] == SSL2_MT_CLIENT_HELLO) || 18655714Skris (p[2] == SSL2_MT_SERVER_HELLO)))) 18755714Skris { 18872616Skris SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_NON_SSLV2_INITIAL_PACKET); 18955714Skris return(-1); 19055714Skris } 19155714Skris } 19255714Skris else 19355714Skris { 19455714Skris n=read_n(s,2,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0); 19555714Skris if (n <= 0) return(n); /* error or non-blocking */ 19655714Skris } 19755714Skris /* part read stuff */ 19855714Skris 19955714Skris s->rstate=SSL_ST_READ_BODY; 20055714Skris p=s->packet; 20155714Skris /* Do header */ 20255714Skris /*s->s2->padding=0;*/ 20355714Skris s->s2->escape=0; 20455714Skris s->s2->rlength=(((unsigned int)p[0])<<8)|((unsigned int)p[1]); 20555714Skris if ((p[0] & TWO_BYTE_BIT)) /* Two byte header? */ 20655714Skris { 20755714Skris s->s2->three_byte_header=0; 20855714Skris s->s2->rlength&=TWO_BYTE_MASK; 20955714Skris } 21055714Skris else 21155714Skris { 21255714Skris s->s2->three_byte_header=1; 21355714Skris s->s2->rlength&=THREE_BYTE_MASK; 21455714Skris 21555714Skris /* security >s2->escape */ 21655714Skris s->s2->escape=((p[0] & SEC_ESC_BIT))?1:0; 21755714Skris } 21855714Skris } 21955714Skris 22055714Skris if (s->rstate == SSL_ST_READ_BODY) 22155714Skris { 22255714Skris n=s->s2->rlength+2+s->s2->three_byte_header; 22355714Skris if (n > (int)s->packet_length) 22455714Skris { 22555714Skris n-=s->packet_length; 22655714Skris i=read_n(s,(unsigned int)n,(unsigned int)n,1); 22755714Skris if (i <= 0) return(i); /* ERROR */ 22855714Skris } 22955714Skris 23055714Skris p= &(s->packet[2]); 23155714Skris s->rstate=SSL_ST_READ_HEADER; 23255714Skris if (s->s2->three_byte_header) 23355714Skris s->s2->padding= *(p++); 23455714Skris else s->s2->padding=0; 23555714Skris 23655714Skris /* Data portion */ 23755714Skris if (s->s2->clear_text) 23855714Skris { 23955714Skris s->s2->mac_data=p; 24055714Skris s->s2->ract_data=p; 24155714Skris s->s2->pad_data=NULL; 24255714Skris } 24355714Skris else 24455714Skris { 24555714Skris mac_size=EVP_MD_size(s->read_hash); 24655714Skris s->s2->mac_data=p; 24755714Skris s->s2->ract_data= &p[mac_size]; 24855714Skris s->s2->pad_data= &p[mac_size+ 24955714Skris s->s2->rlength-s->s2->padding]; 25055714Skris } 25155714Skris 25255714Skris s->s2->ract_data_length=s->s2->rlength; 25355714Skris /* added a check for length > max_size in case 25455714Skris * encryption was not turned on yet due to an error */ 25555714Skris if ((!s->s2->clear_text) && 25655714Skris (s->s2->rlength >= mac_size)) 25755714Skris { 25855714Skris ssl2_enc(s,0); 25955714Skris s->s2->ract_data_length-=mac_size; 26055714Skris ssl2_mac(s,mac,0); 26155714Skris s->s2->ract_data_length-=s->s2->padding; 26255714Skris if ( (memcmp(mac,s->s2->mac_data, 26355714Skris (unsigned int)mac_size) != 0) || 26455714Skris (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) 26555714Skris { 26672616Skris SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE); 26755714Skris return(-1); 26855714Skris } 26955714Skris } 27055714Skris INC32(s->s2->read_sequence); /* expect next number */ 27155714Skris /* s->s2->ract_data is now available for processing */ 27255714Skris 27372616Skris /* Possibly the packet that we just read had 0 actual data bytes. 27472616Skris * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.) 27572616Skris * In this case, returning 0 would be interpreted by the caller 27672616Skris * as indicating EOF, so it's not a good idea. Instead, we just 27772616Skris * continue reading; thus ssl2_read_internal may have to process 27872616Skris * multiple packets before it can return. 27972616Skris * 28072616Skris * [Note that using select() for blocking sockets *never* guarantees 28155714Skris * that the next SSL_read will not block -- the available 28272616Skris * data may contain incomplete packets, and except for SSL 2, 28372616Skris * renegotiation can confuse things even more.] */ 28455714Skris 28555714Skris goto ssl2_read_again; /* This should really be 28672616Skris * "return ssl2_read(s,buf,len)", 28772616Skris * but that would allow for 28872616Skris * denial-of-service attacks if a 28972616Skris * C compiler is used that does not 29072616Skris * recognize end-recursion. */ 29155714Skris } 29255714Skris else 29355714Skris { 29472616Skris SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_STATE); 29555714Skris return(-1); 29655714Skris } 29755714Skris } 29855714Skris 29972616Skrisint ssl2_read(SSL *s, void *buf, int len) 30072616Skris { 30172616Skris return ssl2_read_internal(s, buf, len, 0); 30272616Skris } 30372616Skris 30476870Skrisint ssl2_peek(SSL *s, void *buf, int len) 30572616Skris { 30672616Skris return ssl2_read_internal(s, buf, len, 1); 30772616Skris } 30872616Skris 30955714Skrisstatic int read_n(SSL *s, unsigned int n, unsigned int max, 31055714Skris unsigned int extend) 31155714Skris { 31255714Skris int i,off,newb; 31355714Skris 31455714Skris /* if there is stuff still in the buffer from a previous read, 31555714Skris * and there is more than we want, take some. */ 31655714Skris if (s->s2->rbuf_left >= (int)n) 31755714Skris { 31855714Skris if (extend) 31955714Skris s->packet_length+=n; 32055714Skris else 32155714Skris { 32255714Skris s->packet= &(s->s2->rbuf[s->s2->rbuf_offs]); 32355714Skris s->packet_length=n; 32455714Skris } 32555714Skris s->s2->rbuf_left-=n; 32655714Skris s->s2->rbuf_offs+=n; 32755714Skris return(n); 32855714Skris } 32955714Skris 33055714Skris if (!s->read_ahead) max=n; 33155714Skris if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2)) 33255714Skris max=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2; 33355714Skris 33455714Skris 33555714Skris /* Else we want more than we have. 33655714Skris * First, if there is some left or we want to extend */ 33755714Skris off=0; 33855714Skris if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend)) 33955714Skris { 34055714Skris newb=s->s2->rbuf_left; 34155714Skris if (extend) 34255714Skris { 34355714Skris off=s->packet_length; 34455714Skris if (s->packet != s->s2->rbuf) 34555714Skris memcpy(s->s2->rbuf,s->packet, 34655714Skris (unsigned int)newb+off); 34755714Skris } 34855714Skris else if (s->s2->rbuf_offs != 0) 34955714Skris { 35055714Skris memcpy(s->s2->rbuf,&(s->s2->rbuf[s->s2->rbuf_offs]), 35155714Skris (unsigned int)newb); 35255714Skris s->s2->rbuf_offs=0; 35355714Skris } 35455714Skris s->s2->rbuf_left=0; 35555714Skris } 35655714Skris else 35755714Skris newb=0; 35855714Skris 35955714Skris /* off is the offset to start writing too. 36055714Skris * r->s2->rbuf_offs is the 'unread data', now 0. 36155714Skris * newb is the number of new bytes so far 36255714Skris */ 36355714Skris s->packet=s->s2->rbuf; 36455714Skris while (newb < (int)n) 36555714Skris { 36655714Skris clear_sys_error(); 36755714Skris if (s->rbio != NULL) 36855714Skris { 36955714Skris s->rwstate=SSL_READING; 37055714Skris i=BIO_read(s->rbio,(char *)&(s->s2->rbuf[off+newb]), 37155714Skris max-newb); 37255714Skris } 37355714Skris else 37455714Skris { 37555714Skris SSLerr(SSL_F_READ_N,SSL_R_READ_BIO_NOT_SET); 37655714Skris i= -1; 37755714Skris } 37855714Skris#ifdef PKT_DEBUG 37955714Skris if (s->debug & 0x01) sleep(1); 38055714Skris#endif 38155714Skris if (i <= 0) 38255714Skris { 38355714Skris s->s2->rbuf_left+=newb; 38455714Skris return(i); 38555714Skris } 38655714Skris newb+=i; 38755714Skris } 38855714Skris 38955714Skris /* record unread data */ 39055714Skris if (newb > (int)n) 39155714Skris { 39255714Skris s->s2->rbuf_offs=n+off; 39355714Skris s->s2->rbuf_left=newb-n; 39455714Skris } 39555714Skris else 39655714Skris { 39755714Skris s->s2->rbuf_offs=0; 39855714Skris s->s2->rbuf_left=0; 39955714Skris } 40055714Skris if (extend) 40155714Skris s->packet_length+=n; 40255714Skris else 40355714Skris s->packet_length=n; 40455714Skris s->rwstate=SSL_NOTHING; 40555714Skris return(n); 40655714Skris } 40755714Skris 40855714Skrisint ssl2_write(SSL *s, const void *_buf, int len) 40955714Skris { 41055714Skris const unsigned char *buf=_buf; 41155714Skris unsigned int n,tot; 41255714Skris int i; 41355714Skris 41455714Skris if (SSL_in_init(s) && !s->in_handshake) 41555714Skris { 41655714Skris i=s->handshake_func(s); 41755714Skris if (i < 0) return(i); 41855714Skris if (i == 0) 41955714Skris { 42055714Skris SSLerr(SSL_F_SSL2_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE); 42155714Skris return(-1); 42255714Skris } 42355714Skris } 42455714Skris 42555714Skris if (s->error) 42655714Skris { 42755714Skris ssl2_write_error(s); 42855714Skris if (s->error) 42955714Skris return(-1); 43055714Skris } 43155714Skris 43255714Skris clear_sys_error(); 43355714Skris s->rwstate=SSL_NOTHING; 43455714Skris if (len <= 0) return(len); 43555714Skris 43655714Skris tot=s->s2->wnum; 43755714Skris s->s2->wnum=0; 43855714Skris 43955714Skris n=(len-tot); 44055714Skris for (;;) 44155714Skris { 44255714Skris i=do_ssl_write(s,&(buf[tot]),n); 44355714Skris if (i <= 0) 44455714Skris { 44555714Skris s->s2->wnum=tot; 44655714Skris return(i); 44755714Skris } 44855714Skris if ((i == (int)n) || 44955714Skris (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) 45055714Skris { 45155714Skris return(tot+i); 45255714Skris } 45355714Skris 45455714Skris n-=i; 45555714Skris tot+=i; 45655714Skris } 45755714Skris } 45855714Skris 45955714Skrisstatic int write_pending(SSL *s, const unsigned char *buf, unsigned int len) 46055714Skris { 46155714Skris int i; 46255714Skris 46355714Skris /* s->s2->wpend_len != 0 MUST be true. */ 46455714Skris 46555714Skris /* check that they have given us the same buffer to 46655714Skris * write */ 46755714Skris if ((s->s2->wpend_tot > (int)len) || 46855714Skris ((s->s2->wpend_buf != buf) && 46955714Skris !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))) 47055714Skris { 47155714Skris SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY); 47255714Skris return(-1); 47355714Skris } 47455714Skris 47555714Skris for (;;) 47655714Skris { 47755714Skris clear_sys_error(); 47855714Skris if (s->wbio != NULL) 47955714Skris { 48055714Skris s->rwstate=SSL_WRITING; 48155714Skris i=BIO_write(s->wbio, 48255714Skris (char *)&(s->s2->write_ptr[s->s2->wpend_off]), 48355714Skris (unsigned int)s->s2->wpend_len); 48455714Skris } 48555714Skris else 48655714Skris { 48755714Skris SSLerr(SSL_F_WRITE_PENDING,SSL_R_WRITE_BIO_NOT_SET); 48855714Skris i= -1; 48955714Skris } 49055714Skris#ifdef PKT_DEBUG 49155714Skris if (s->debug & 0x01) sleep(1); 49255714Skris#endif 49355714Skris if (i == s->s2->wpend_len) 49455714Skris { 49555714Skris s->s2->wpend_len=0; 49655714Skris s->rwstate=SSL_NOTHING; 49755714Skris return(s->s2->wpend_ret); 49855714Skris } 49955714Skris else if (i <= 0) 50055714Skris return(i); 50155714Skris s->s2->wpend_off+=i; 50255714Skris s->s2->wpend_len-=i; 50355714Skris } 50455714Skris } 50555714Skris 50655714Skrisstatic int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) 50755714Skris { 50855714Skris unsigned int j,k,olen,p,mac_size,bs; 50955714Skris register unsigned char *pp; 51055714Skris 51155714Skris olen=len; 51255714Skris 51355714Skris /* first check if there is data from an encryption waiting to 51455714Skris * be sent - it must be sent because the other end is waiting. 51555714Skris * This will happen with non-blocking IO. We print it and then 51655714Skris * return. 51755714Skris */ 51855714Skris if (s->s2->wpend_len != 0) return(write_pending(s,buf,len)); 51955714Skris 52055714Skris /* set mac_size to mac size */ 52155714Skris if (s->s2->clear_text) 52255714Skris mac_size=0; 52355714Skris else 52455714Skris mac_size=EVP_MD_size(s->write_hash); 52555714Skris 52655714Skris /* lets set the pad p */ 52755714Skris if (s->s2->clear_text) 52855714Skris { 52955714Skris if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) 53055714Skris len=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; 53155714Skris p=0; 53255714Skris s->s2->three_byte_header=0; 53355714Skris /* len=len; */ 53455714Skris } 53555714Skris else 53655714Skris { 53755714Skris bs=EVP_CIPHER_CTX_block_size(s->enc_read_ctx); 53855714Skris j=len+mac_size; 53972616Skris /* Two-byte headers allow for a larger record length than 54072616Skris * three-byte headers, but we can't use them if we need 54172616Skris * padding or if we have to set the escape bit. */ 54255714Skris if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) && 54355714Skris (!s->s2->escape)) 54455714Skris { 54555714Skris if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) 54655714Skris j=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; 54755714Skris /* set k to the max number of bytes with 2 54855714Skris * byte header */ 54955714Skris k=j-(j%bs); 55055714Skris /* how many data bytes? */ 55155714Skris len=k-mac_size; 55255714Skris s->s2->three_byte_header=0; 55355714Skris p=0; 55455714Skris } 55555714Skris else if ((bs <= 1) && (!s->s2->escape)) 55655714Skris { 55772616Skris /* j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus 55872616Skris * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER */ 55955714Skris s->s2->three_byte_header=0; 56055714Skris p=0; 56155714Skris } 56272616Skris else /* we may have to use a 3 byte header */ 56355714Skris { 56472616Skris /* If s->s2->escape is not set, then 56572616Skris * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus 56672616Skris * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. */ 56755714Skris p=(j%bs); 56855714Skris p=(p == 0)?0:(bs-p); 56955714Skris if (s->s2->escape) 57072616Skris { 57155714Skris s->s2->three_byte_header=1; 57272616Skris if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) 57372616Skris j=SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER; 57472616Skris } 57555714Skris else 57655714Skris s->s2->three_byte_header=(p == 0)?0:1; 57755714Skris } 57855714Skris } 57972616Skris 58072616Skris /* Now 58172616Skris * j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 58272616Skris * holds, and if s->s2->three_byte_header is set, then even 58372616Skris * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER. 58472616Skris */ 58572616Skris 58655714Skris /* mac_size is the number of MAC bytes 58755714Skris * len is the number of data bytes we are going to send 58855714Skris * p is the number of padding bytes 58972616Skris * (if it is a two-byte header, then p == 0) */ 59055714Skris 59155714Skris s->s2->wlength=len; 59255714Skris s->s2->padding=p; 59355714Skris s->s2->mac_data= &(s->s2->wbuf[3]); 59455714Skris s->s2->wact_data= &(s->s2->wbuf[3+mac_size]); 59555714Skris /* we copy the data into s->s2->wbuf */ 59655714Skris memcpy(s->s2->wact_data,buf,len); 59755714Skris#ifdef PURIFY 59855714Skris if (p) 59955714Skris memset(&(s->s2->wact_data[len]),0,p); 60055714Skris#endif 60155714Skris 60255714Skris if (!s->s2->clear_text) 60355714Skris { 60455714Skris s->s2->wact_data_length=len+p; 60555714Skris ssl2_mac(s,s->s2->mac_data,1); 60655714Skris s->s2->wlength+=p+mac_size; 60755714Skris ssl2_enc(s,1); 60855714Skris } 60955714Skris 61055714Skris /* package up the header */ 61155714Skris s->s2->wpend_len=s->s2->wlength; 61255714Skris if (s->s2->three_byte_header) /* 3 byte header */ 61355714Skris { 61455714Skris pp=s->s2->mac_data; 61555714Skris pp-=3; 61655714Skris pp[0]=(s->s2->wlength>>8)&(THREE_BYTE_MASK>>8); 61755714Skris if (s->s2->escape) pp[0]|=SEC_ESC_BIT; 61855714Skris pp[1]=s->s2->wlength&0xff; 61955714Skris pp[2]=s->s2->padding; 62055714Skris s->s2->wpend_len+=3; 62155714Skris } 62255714Skris else 62355714Skris { 62455714Skris pp=s->s2->mac_data; 62555714Skris pp-=2; 62655714Skris pp[0]=((s->s2->wlength>>8)&(TWO_BYTE_MASK>>8))|TWO_BYTE_BIT; 62755714Skris pp[1]=s->s2->wlength&0xff; 62855714Skris s->s2->wpend_len+=2; 62955714Skris } 63055714Skris s->s2->write_ptr=pp; 63155714Skris 63255714Skris INC32(s->s2->write_sequence); /* expect next number */ 63355714Skris 63455714Skris /* lets try to actually write the data */ 63555714Skris s->s2->wpend_tot=olen; 63655714Skris s->s2->wpend_buf=buf; 63755714Skris 63855714Skris s->s2->wpend_ret=len; 63955714Skris 64055714Skris s->s2->wpend_off=0; 64155714Skris return(write_pending(s,buf,olen)); 64255714Skris } 64355714Skris 64455714Skrisint ssl2_part_read(SSL *s, unsigned long f, int i) 64555714Skris { 64655714Skris unsigned char *p; 64755714Skris int j; 64855714Skris 64955714Skris /* check for error */ 65055714Skris if ((s->init_num == 0) && (i >= 3)) 65155714Skris { 65255714Skris p=(unsigned char *)s->init_buf->data; 65355714Skris if (p[0] == SSL2_MT_ERROR) 65455714Skris { 65555714Skris j=(p[1]<<8)|p[2]; 65655714Skris SSLerr((int)f,ssl_mt_error(j)); 65755714Skris } 65855714Skris } 65955714Skris 66055714Skris if (i < 0) 66155714Skris { 66255714Skris /* ssl2_return_error(s); */ 66355714Skris /* for non-blocking io, 66455714Skris * this is not fatal */ 66555714Skris return(i); 66655714Skris } 66755714Skris else 66855714Skris { 66955714Skris s->init_num+=i; 67055714Skris return(0); 67155714Skris } 67255714Skris } 67355714Skris 67455714Skrisint ssl2_do_write(SSL *s) 67555714Skris { 67655714Skris int ret; 67755714Skris 67855714Skris ret=ssl2_write(s,&s->init_buf->data[s->init_off],s->init_num); 67955714Skris if (ret == s->init_num) 68055714Skris return(1); 68155714Skris if (ret < 0) 68255714Skris return(-1); 68355714Skris s->init_off+=ret; 68455714Skris s->init_num-=ret; 68555714Skris return(0); 68655714Skris } 68755714Skris 68855714Skrisstatic int ssl_mt_error(int n) 68955714Skris { 69055714Skris int ret; 69155714Skris 69255714Skris switch (n) 69355714Skris { 69455714Skris case SSL2_PE_NO_CIPHER: 69555714Skris ret=SSL_R_PEER_ERROR_NO_CIPHER; 69655714Skris break; 69755714Skris case SSL2_PE_NO_CERTIFICATE: 69855714Skris ret=SSL_R_PEER_ERROR_NO_CERTIFICATE; 69955714Skris break; 70055714Skris case SSL2_PE_BAD_CERTIFICATE: 70155714Skris ret=SSL_R_PEER_ERROR_CERTIFICATE; 70255714Skris break; 70355714Skris case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE: 70455714Skris ret=SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; 70555714Skris break; 70655714Skris default: 70755714Skris ret=SSL_R_UNKNOWN_REMOTE_ERROR_TYPE; 70855714Skris break; 70955714Skris } 71055714Skris return(ret); 71155714Skris } 71259194Skris#else /* !NO_SSL2 */ 71355949Skris 71459194Skris# if PEDANTIC 71559194Skrisstatic void *dummy=&dummy; 71659194Skris# endif 71759194Skris 71855949Skris#endif 719