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