os/ossrv/ssl/libssl/src/s2_pkt.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libssl/src/s2_pkt.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,737 @@
     1.4 +/* ssl/s2_pkt.c */
     1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
     1.6 + * All rights reserved.
     1.7 + *
     1.8 + * This package is an SSL implementation written
     1.9 + * by Eric Young (eay@cryptsoft.com).
    1.10 + * The implementation was written so as to conform with Netscapes SSL.
    1.11 + * 
    1.12 + * This library is free for commercial and non-commercial use as long as
    1.13 + * the following conditions are aheared to.  The following conditions
    1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
    1.15 + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    1.16 + * included with this distribution is covered by the same copyright terms
    1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    1.18 + * 
    1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
    1.20 + * the code are not to be removed.
    1.21 + * If this package is used in a product, Eric Young should be given attribution
    1.22 + * as the author of the parts of the library used.
    1.23 + * This can be in the form of a textual message at program startup or
    1.24 + * in documentation (online or textual) provided with the package.
    1.25 + * 
    1.26 + * Redistribution and use in source and binary forms, with or without
    1.27 + * modification, are permitted provided that the following conditions
    1.28 + * are met:
    1.29 + * 1. Redistributions of source code must retain the copyright
    1.30 + *    notice, this list of conditions and the following disclaimer.
    1.31 + * 2. Redistributions in binary form must reproduce the above copyright
    1.32 + *    notice, this list of conditions and the following disclaimer in the
    1.33 + *    documentation and/or other materials provided with the distribution.
    1.34 + * 3. All advertising materials mentioning features or use of this software
    1.35 + *    must display the following acknowledgement:
    1.36 + *    "This product includes cryptographic software written by
    1.37 + *     Eric Young (eay@cryptsoft.com)"
    1.38 + *    The word 'cryptographic' can be left out if the rouines from the library
    1.39 + *    being used are not cryptographic related :-).
    1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from 
    1.41 + *    the apps directory (application code) you must include an acknowledgement:
    1.42 + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    1.43 + * 
    1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.47 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.54 + * SUCH DAMAGE.
    1.55 + * 
    1.56 + * The licence and distribution terms for any publically available version or
    1.57 + * derivative of this code cannot be changed.  i.e. this code cannot simply be
    1.58 + * copied and put under another distribution licence
    1.59 + * [including the GNU Public Licence.]
    1.60 + */
    1.61 +/* ====================================================================
    1.62 + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
    1.63 + *
    1.64 + * Redistribution and use in source and binary forms, with or without
    1.65 + * modification, are permitted provided that the following conditions
    1.66 + * are met:
    1.67 + *
    1.68 + * 1. Redistributions of source code must retain the above copyright
    1.69 + *    notice, this list of conditions and the following disclaimer. 
    1.70 + *
    1.71 + * 2. Redistributions in binary form must reproduce the above copyright
    1.72 + *    notice, this list of conditions and the following disclaimer in
    1.73 + *    the documentation and/or other materials provided with the
    1.74 + *    distribution.
    1.75 + *
    1.76 + * 3. All advertising materials mentioning features or use of this
    1.77 + *    software must display the following acknowledgment:
    1.78 + *    "This product includes software developed by the OpenSSL Project
    1.79 + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
    1.80 + *
    1.81 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    1.82 + *    endorse or promote products derived from this software without
    1.83 + *    prior written permission. For written permission, please contact
    1.84 + *    openssl-core@openssl.org.
    1.85 + *
    1.86 + * 5. Products derived from this software may not be called "OpenSSL"
    1.87 + *    nor may "OpenSSL" appear in their names without prior written
    1.88 + *    permission of the OpenSSL Project.
    1.89 + *
    1.90 + * 6. Redistributions of any form whatsoever must retain the following
    1.91 + *    acknowledgment:
    1.92 + *    "This product includes software developed by the OpenSSL Project
    1.93 + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
    1.94 + *
    1.95 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    1.96 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.97 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.98 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    1.99 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   1.100 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   1.101 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   1.102 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   1.103 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   1.104 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   1.105 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   1.106 + * OF THE POSSIBILITY OF SUCH DAMAGE.
   1.107 + * ====================================================================
   1.108 + *
   1.109 + * This product includes cryptographic software written by Eric Young
   1.110 + * (eay@cryptsoft.com).  This product includes software written by Tim
   1.111 + * Hudson (tjh@cryptsoft.com).
   1.112 + *
   1.113 + */
   1.114 +
   1.115 +#include "ssl_locl.h"
   1.116 +#ifndef OPENSSL_NO_SSL2
   1.117 +#include <stdio.h>
   1.118 +#include <errno.h>
   1.119 +#define USE_SOCKETS
   1.120 +
   1.121 +static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend);
   1.122 +static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
   1.123 +static int write_pending(SSL *s, const unsigned char *buf, unsigned int len);
   1.124 +static int ssl_mt_error(int n);
   1.125 +
   1.126 +
   1.127 +/* SSL 2.0 imlementation for SSL_read/SSL_peek -
   1.128 + * This routine will return 0 to len bytes, decrypted etc if required.
   1.129 + */
   1.130 +static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
   1.131 +	{
   1.132 +	int n;
   1.133 +	unsigned char mac[MAX_MAC_SIZE];
   1.134 +	unsigned char *p;
   1.135 +	int i;
   1.136 +	unsigned int mac_size;
   1.137 +
   1.138 + ssl2_read_again:
   1.139 +	if (SSL_in_init(s) && !s->in_handshake)
   1.140 +		{
   1.141 +		n=s->handshake_func(s);
   1.142 +		if (n < 0) return(n);
   1.143 +		if (n == 0)
   1.144 +			{
   1.145 +			SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_SSL_HANDSHAKE_FAILURE);
   1.146 +			return(-1);
   1.147 +			}
   1.148 +		}
   1.149 +
   1.150 +	clear_sys_error();
   1.151 +	s->rwstate=SSL_NOTHING;
   1.152 +	if (len <= 0) return(len);
   1.153 +
   1.154 +	if (s->s2->ract_data_length != 0) /* read from buffer */
   1.155 +		{
   1.156 +		if (len > s->s2->ract_data_length)
   1.157 +			n=s->s2->ract_data_length;
   1.158 +		else
   1.159 +			n=len;
   1.160 +
   1.161 +		memcpy(buf,s->s2->ract_data,(unsigned int)n);
   1.162 +		if (!peek)
   1.163 +			{
   1.164 +			s->s2->ract_data_length-=n;
   1.165 +			s->s2->ract_data+=n;
   1.166 +			if (s->s2->ract_data_length == 0)
   1.167 +				s->rstate=SSL_ST_READ_HEADER;
   1.168 +			}
   1.169 +
   1.170 +		return(n);
   1.171 +		}
   1.172 +
   1.173 +	/* s->s2->ract_data_length == 0
   1.174 +	 * 
   1.175 +	 * Fill the buffer, then goto ssl2_read_again.
   1.176 +	 */
   1.177 +
   1.178 +	if (s->rstate == SSL_ST_READ_HEADER)
   1.179 +		{
   1.180 +		if (s->first_packet)
   1.181 +			{
   1.182 +			n=read_n(s,5,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
   1.183 +			if (n <= 0) return(n); /* error or non-blocking */
   1.184 +			s->first_packet=0;
   1.185 +			p=s->packet;
   1.186 +			if (!((p[0] & 0x80) && (
   1.187 +				(p[2] == SSL2_MT_CLIENT_HELLO) ||
   1.188 +				(p[2] == SSL2_MT_SERVER_HELLO))))
   1.189 +				{
   1.190 +				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_NON_SSLV2_INITIAL_PACKET);
   1.191 +				return(-1);
   1.192 +				}
   1.193 +			}
   1.194 +		else
   1.195 +			{
   1.196 +			n=read_n(s,2,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
   1.197 +			if (n <= 0) return(n); /* error or non-blocking */
   1.198 +			}
   1.199 +		/* part read stuff */
   1.200 +
   1.201 +		s->rstate=SSL_ST_READ_BODY;
   1.202 +		p=s->packet;
   1.203 +		/* Do header */
   1.204 +		/*s->s2->padding=0;*/
   1.205 +		s->s2->escape=0;
   1.206 +		s->s2->rlength=(((unsigned int)p[0])<<8)|((unsigned int)p[1]);
   1.207 +		if ((p[0] & TWO_BYTE_BIT))		/* Two byte header? */
   1.208 +			{
   1.209 +			s->s2->three_byte_header=0;
   1.210 +			s->s2->rlength&=TWO_BYTE_MASK;	
   1.211 +			}
   1.212 +		else
   1.213 +			{
   1.214 +			s->s2->three_byte_header=1;
   1.215 +			s->s2->rlength&=THREE_BYTE_MASK;
   1.216 +
   1.217 +			/* security >s2->escape */
   1.218 +			s->s2->escape=((p[0] & SEC_ESC_BIT))?1:0;
   1.219 +			}
   1.220 +		}
   1.221 +
   1.222 +	if (s->rstate == SSL_ST_READ_BODY)
   1.223 +		{
   1.224 +		n=s->s2->rlength+2+s->s2->three_byte_header;
   1.225 +		if (n > (int)s->packet_length)
   1.226 +			{
   1.227 +			n-=s->packet_length;
   1.228 +			i=read_n(s,(unsigned int)n,(unsigned int)n,1);
   1.229 +			if (i <= 0) return(i); /* ERROR */
   1.230 +			}
   1.231 +
   1.232 +		p= &(s->packet[2]);
   1.233 +		s->rstate=SSL_ST_READ_HEADER;
   1.234 +		if (s->s2->three_byte_header)
   1.235 +			s->s2->padding= *(p++);
   1.236 +		else	s->s2->padding=0;
   1.237 +
   1.238 +		/* Data portion */
   1.239 +		if (s->s2->clear_text)
   1.240 +			{
   1.241 +			mac_size = 0;
   1.242 +			s->s2->mac_data=p;
   1.243 +			s->s2->ract_data=p;
   1.244 +			if (s->s2->padding)
   1.245 +				{
   1.246 +				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
   1.247 +				return(-1);
   1.248 +				}
   1.249 +			}
   1.250 +		else
   1.251 +			{
   1.252 +			mac_size=EVP_MD_size(s->read_hash);
   1.253 +			OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
   1.254 +			s->s2->mac_data=p;
   1.255 +			s->s2->ract_data= &p[mac_size];
   1.256 +			if (s->s2->padding + mac_size > s->s2->rlength)
   1.257 +				{
   1.258 +				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
   1.259 +				return(-1);
   1.260 +				}
   1.261 +			}
   1.262 +
   1.263 +		s->s2->ract_data_length=s->s2->rlength;
   1.264 +		/* added a check for length > max_size in case
   1.265 +		 * encryption was not turned on yet due to an error */
   1.266 +		if ((!s->s2->clear_text) &&
   1.267 +			(s->s2->rlength >= mac_size))
   1.268 +			{
   1.269 +			ssl2_enc(s,0);
   1.270 +			s->s2->ract_data_length-=mac_size;
   1.271 +			ssl2_mac(s,mac,0);
   1.272 +			s->s2->ract_data_length-=s->s2->padding;
   1.273 +			if (	(memcmp(mac,s->s2->mac_data,
   1.274 +				(unsigned int)mac_size) != 0) ||
   1.275 +				(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
   1.276 +				{
   1.277 +				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
   1.278 +				return(-1);
   1.279 +				}
   1.280 +			}
   1.281 +		INC32(s->s2->read_sequence); /* expect next number */
   1.282 +		/* s->s2->ract_data is now available for processing */
   1.283 +
   1.284 +		/* Possibly the packet that we just read had 0 actual data bytes.
   1.285 +		 * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.)
   1.286 +		 * In this case, returning 0 would be interpreted by the caller
   1.287 +		 * as indicating EOF, so it's not a good idea.  Instead, we just
   1.288 +		 * continue reading; thus ssl2_read_internal may have to process
   1.289 +		 * multiple packets before it can return.
   1.290 +		 *
   1.291 +		 * [Note that using select() for blocking sockets *never* guarantees
   1.292 +		 * that the next SSL_read will not block -- the available
   1.293 +		 * data may contain incomplete packets, and except for SSL 2,
   1.294 +		 * renegotiation can confuse things even more.] */
   1.295 +
   1.296 +		goto ssl2_read_again; /* This should really be
   1.297 +		                       * "return ssl2_read(s,buf,len)",
   1.298 +		                       * but that would allow for
   1.299 +		                       * denial-of-service attacks if a
   1.300 +		                       * C compiler is used that does not
   1.301 +		                       * recognize end-recursion. */
   1.302 +		}
   1.303 +	else
   1.304 +		{
   1.305 +		SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_STATE);
   1.306 +			return(-1);
   1.307 +		}
   1.308 +	}
   1.309 +
   1.310 +int ssl2_read(SSL *s, void *buf, int len)
   1.311 +	{
   1.312 +	return ssl2_read_internal(s, buf, len, 0);
   1.313 +	}
   1.314 +
   1.315 +int ssl2_peek(SSL *s, void *buf, int len)
   1.316 +	{
   1.317 +	return ssl2_read_internal(s, buf, len, 1);
   1.318 +	}
   1.319 +
   1.320 +static int read_n(SSL *s, unsigned int n, unsigned int max,
   1.321 +	     unsigned int extend)
   1.322 +	{
   1.323 +	int i,off,newb;
   1.324 +
   1.325 +	/* if there is stuff still in the buffer from a previous read,
   1.326 +	 * and there is more than we want, take some. */
   1.327 +	if (s->s2->rbuf_left >= (int)n)
   1.328 +		{
   1.329 +		if (extend)
   1.330 +			s->packet_length+=n;
   1.331 +		else
   1.332 +			{
   1.333 +			s->packet= &(s->s2->rbuf[s->s2->rbuf_offs]);
   1.334 +			s->packet_length=n;
   1.335 +			}
   1.336 +		s->s2->rbuf_left-=n;
   1.337 +		s->s2->rbuf_offs+=n;
   1.338 +		return(n);
   1.339 +		}
   1.340 +
   1.341 +	if (!s->read_ahead) max=n;
   1.342 +	if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2))
   1.343 +		max=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2;
   1.344 +	
   1.345 +
   1.346 +	/* Else we want more than we have.
   1.347 +	 * First, if there is some left or we want to extend */
   1.348 +	off=0;
   1.349 +	if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend))
   1.350 +		{
   1.351 +		newb=s->s2->rbuf_left;
   1.352 +		if (extend)
   1.353 +			{
   1.354 +			off=s->packet_length;
   1.355 +			if (s->packet != s->s2->rbuf)
   1.356 +				memcpy(s->s2->rbuf,s->packet,
   1.357 +					(unsigned int)newb+off);
   1.358 +			}
   1.359 +		else if (s->s2->rbuf_offs != 0)
   1.360 +			{
   1.361 +			memcpy(s->s2->rbuf,&(s->s2->rbuf[s->s2->rbuf_offs]),
   1.362 +				(unsigned int)newb);
   1.363 +			s->s2->rbuf_offs=0;
   1.364 +			}
   1.365 +		s->s2->rbuf_left=0;
   1.366 +		}
   1.367 +	else
   1.368 +		newb=0;
   1.369 +
   1.370 +	/* off is the offset to start writing too.
   1.371 +	 * r->s2->rbuf_offs is the 'unread data', now 0. 
   1.372 +	 * newb is the number of new bytes so far
   1.373 +	 */
   1.374 +	s->packet=s->s2->rbuf;
   1.375 +	while (newb < (int)n)
   1.376 +		{
   1.377 +		clear_sys_error();
   1.378 +		if (s->rbio != NULL)
   1.379 +			{
   1.380 +			s->rwstate=SSL_READING;
   1.381 +			i=BIO_read(s->rbio,(char *)&(s->s2->rbuf[off+newb]),
   1.382 +				max-newb);
   1.383 +			}
   1.384 +		else
   1.385 +			{
   1.386 +			SSLerr(SSL_F_READ_N,SSL_R_READ_BIO_NOT_SET);
   1.387 +			i= -1;
   1.388 +			}
   1.389 +#ifdef PKT_DEBUG
   1.390 +		if (s->debug & 0x01) sleep(1);
   1.391 +#endif
   1.392 +		if (i <= 0)
   1.393 +			{
   1.394 +			s->s2->rbuf_left+=newb;
   1.395 +			return(i);
   1.396 +			}
   1.397 +		newb+=i;
   1.398 +		}
   1.399 +
   1.400 +	/* record unread data */
   1.401 +	if (newb > (int)n)
   1.402 +		{
   1.403 +		s->s2->rbuf_offs=n+off;
   1.404 +		s->s2->rbuf_left=newb-n;
   1.405 +		}
   1.406 +	else
   1.407 +		{
   1.408 +		s->s2->rbuf_offs=0;
   1.409 +		s->s2->rbuf_left=0;
   1.410 +		}
   1.411 +	if (extend)
   1.412 +		s->packet_length+=n;
   1.413 +	else
   1.414 +		s->packet_length=n;
   1.415 +	s->rwstate=SSL_NOTHING;
   1.416 +	return(n);
   1.417 +	}
   1.418 +
   1.419 +int ssl2_write(SSL *s, const void *_buf, int len)
   1.420 +	{
   1.421 +	const unsigned char *buf=_buf;
   1.422 +	unsigned int n,tot;
   1.423 +	int i;
   1.424 +
   1.425 +	if (SSL_in_init(s) && !s->in_handshake)
   1.426 +		{
   1.427 +		i=s->handshake_func(s);
   1.428 +		if (i < 0) return(i);
   1.429 +		if (i == 0)
   1.430 +			{
   1.431 +			SSLerr(SSL_F_SSL2_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE);
   1.432 +			return(-1);
   1.433 +			}
   1.434 +		}
   1.435 +
   1.436 +	if (s->error)
   1.437 +		{
   1.438 +		ssl2_write_error(s);
   1.439 +		if (s->error)
   1.440 +			return(-1);
   1.441 +		}
   1.442 +
   1.443 +	clear_sys_error();
   1.444 +	s->rwstate=SSL_NOTHING;
   1.445 +	if (len <= 0) return(len);
   1.446 +
   1.447 +	tot=s->s2->wnum;
   1.448 +	s->s2->wnum=0;
   1.449 +
   1.450 +	n=(len-tot);
   1.451 +	for (;;)
   1.452 +		{
   1.453 +		i=do_ssl_write(s,&(buf[tot]),n);
   1.454 +		if (i <= 0)
   1.455 +			{
   1.456 +			s->s2->wnum=tot;
   1.457 +			return(i);
   1.458 +			}
   1.459 +		if ((i == (int)n) ||
   1.460 +			(s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))
   1.461 +			{
   1.462 +			return(tot+i);
   1.463 +			}
   1.464 +		
   1.465 +		n-=i;
   1.466 +		tot+=i;
   1.467 +		}
   1.468 +	}
   1.469 +
   1.470 +static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
   1.471 +	{
   1.472 +	int i;
   1.473 +
   1.474 +	/* s->s2->wpend_len != 0 MUST be true. */
   1.475 +
   1.476 +	/* check that they have given us the same buffer to
   1.477 +	 * write */
   1.478 +	if ((s->s2->wpend_tot > (int)len) ||
   1.479 +		((s->s2->wpend_buf != buf) &&
   1.480 +		 !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
   1.481 +		{
   1.482 +		SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
   1.483 +		return(-1);
   1.484 +		}
   1.485 +
   1.486 +	for (;;)
   1.487 +		{
   1.488 +		clear_sys_error();
   1.489 +		if (s->wbio != NULL)
   1.490 +			{
   1.491 +			s->rwstate=SSL_WRITING;
   1.492 +			i=BIO_write(s->wbio,
   1.493 +				(char *)&(s->s2->write_ptr[s->s2->wpend_off]),
   1.494 +				(unsigned int)s->s2->wpend_len);
   1.495 +			}
   1.496 +		else
   1.497 +			{
   1.498 +			SSLerr(SSL_F_WRITE_PENDING,SSL_R_WRITE_BIO_NOT_SET);
   1.499 +			i= -1;
   1.500 +			}
   1.501 +#ifdef PKT_DEBUG
   1.502 +		if (s->debug & 0x01) sleep(1);
   1.503 +#endif
   1.504 +		if (i == s->s2->wpend_len)
   1.505 +			{
   1.506 +			s->s2->wpend_len=0;
   1.507 +			s->rwstate=SSL_NOTHING;
   1.508 +			return(s->s2->wpend_ret);
   1.509 +			}
   1.510 +		else if (i <= 0)
   1.511 +			return(i);
   1.512 +		s->s2->wpend_off+=i;
   1.513 +		s->s2->wpend_len-=i;
   1.514 +		}
   1.515 +	}
   1.516 +
   1.517 +static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
   1.518 +	{
   1.519 +	unsigned int j,k,olen,p,mac_size,bs;
   1.520 +	register unsigned char *pp;
   1.521 +
   1.522 +	olen=len;
   1.523 +
   1.524 +	/* first check if there is data from an encryption waiting to
   1.525 +	 * be sent - it must be sent because the other end is waiting.
   1.526 +	 * This will happen with non-blocking IO.  We print it and then
   1.527 +	 * return.
   1.528 +	 */
   1.529 +	if (s->s2->wpend_len != 0) return(write_pending(s,buf,len));
   1.530 +
   1.531 +	/* set mac_size to mac size */
   1.532 +	if (s->s2->clear_text)
   1.533 +		mac_size=0;
   1.534 +	else
   1.535 +		mac_size=EVP_MD_size(s->write_hash);
   1.536 +
   1.537 +	/* lets set the pad p */
   1.538 +	if (s->s2->clear_text)
   1.539 +		{
   1.540 +		if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
   1.541 +			len=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
   1.542 +		p=0;
   1.543 +		s->s2->three_byte_header=0;
   1.544 +		/* len=len; */
   1.545 +		}
   1.546 +	else
   1.547 +		{
   1.548 +		bs=EVP_CIPHER_CTX_block_size(s->enc_read_ctx);
   1.549 +		j=len+mac_size;
   1.550 +		/* Two-byte headers allow for a larger record length than
   1.551 +		 * three-byte headers, but we can't use them if we need
   1.552 +		 * padding or if we have to set the escape bit. */
   1.553 +		if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) &&
   1.554 +			(!s->s2->escape))
   1.555 +			{
   1.556 +			if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
   1.557 +				j=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
   1.558 +			/* set k to the max number of bytes with 2
   1.559 +			 * byte header */
   1.560 +			k=j-(j%bs);
   1.561 +			/* how many data bytes? */
   1.562 +			len=k-mac_size; 
   1.563 +			s->s2->three_byte_header=0;
   1.564 +			p=0;
   1.565 +			}
   1.566 +		else if ((bs <= 1) && (!s->s2->escape))
   1.567 +			{
   1.568 +			/* j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus
   1.569 +			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER */
   1.570 +			s->s2->three_byte_header=0;
   1.571 +			p=0;
   1.572 +			}
   1.573 +		else /* we may have to use a 3 byte header */
   1.574 +			{
   1.575 +			/* If s->s2->escape is not set, then
   1.576 +			 * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus
   1.577 +			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. */
   1.578 +			p=(j%bs);
   1.579 +			p=(p == 0)?0:(bs-p);
   1.580 +			if (s->s2->escape)
   1.581 +				{
   1.582 +				s->s2->three_byte_header=1;
   1.583 +				if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
   1.584 +					j=SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER;
   1.585 +				}
   1.586 +			else
   1.587 +				s->s2->three_byte_header=(p == 0)?0:1;
   1.588 +			}
   1.589 +		}
   1.590 +
   1.591 +	/* Now
   1.592 +	 *      j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER
   1.593 +	 * holds, and if s->s2->three_byte_header is set, then even
   1.594 +	 *      j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER.
   1.595 +	 */
   1.596 +
   1.597 +	/* mac_size is the number of MAC bytes
   1.598 +	 * len is the number of data bytes we are going to send
   1.599 +	 * p is the number of padding bytes
   1.600 +	 * (if it is a two-byte header, then p == 0) */
   1.601 +
   1.602 +	s->s2->wlength=len;
   1.603 +	s->s2->padding=p;
   1.604 +	s->s2->mac_data= &(s->s2->wbuf[3]);
   1.605 +	s->s2->wact_data= &(s->s2->wbuf[3+mac_size]);
   1.606 +	/* we copy the data into s->s2->wbuf */
   1.607 +	memcpy(s->s2->wact_data,buf,len);
   1.608 +	if (p)
   1.609 +		memset(&(s->s2->wact_data[len]),0,p); /* arbitrary padding */
   1.610 +
   1.611 +	if (!s->s2->clear_text)
   1.612 +		{
   1.613 +		s->s2->wact_data_length=len+p;
   1.614 +		ssl2_mac(s,s->s2->mac_data,1);
   1.615 +		s->s2->wlength+=p+mac_size;
   1.616 +		ssl2_enc(s,1);
   1.617 +		}
   1.618 +
   1.619 +	/* package up the header */
   1.620 +	s->s2->wpend_len=s->s2->wlength;
   1.621 +	if (s->s2->three_byte_header) /* 3 byte header */
   1.622 +		{
   1.623 +		pp=s->s2->mac_data;
   1.624 +		pp-=3;
   1.625 +		pp[0]=(s->s2->wlength>>8)&(THREE_BYTE_MASK>>8);
   1.626 +		if (s->s2->escape) pp[0]|=SEC_ESC_BIT;
   1.627 +		pp[1]=s->s2->wlength&0xff;
   1.628 +		pp[2]=s->s2->padding;
   1.629 +		s->s2->wpend_len+=3;
   1.630 +		}
   1.631 +	else
   1.632 +		{
   1.633 +		pp=s->s2->mac_data;
   1.634 +		pp-=2;
   1.635 +		pp[0]=((s->s2->wlength>>8)&(TWO_BYTE_MASK>>8))|TWO_BYTE_BIT;
   1.636 +		pp[1]=s->s2->wlength&0xff;
   1.637 +		s->s2->wpend_len+=2;
   1.638 +		}
   1.639 +	s->s2->write_ptr=pp;
   1.640 +	
   1.641 +	INC32(s->s2->write_sequence); /* expect next number */
   1.642 +
   1.643 +	/* lets try to actually write the data */
   1.644 +	s->s2->wpend_tot=olen;
   1.645 +	s->s2->wpend_buf=buf;
   1.646 +
   1.647 +	s->s2->wpend_ret=len;
   1.648 +
   1.649 +	s->s2->wpend_off=0;
   1.650 +	return(write_pending(s,buf,olen));
   1.651 +	}
   1.652 +
   1.653 +int ssl2_part_read(SSL *s, unsigned long f, int i)
   1.654 +	{
   1.655 +	unsigned char *p;
   1.656 +	int j;
   1.657 +
   1.658 +	if (i < 0)
   1.659 +		{
   1.660 +		/* ssl2_return_error(s); */
   1.661 +		/* for non-blocking io,
   1.662 +		 * this is not necessarily fatal */
   1.663 +		return(i);
   1.664 +		}
   1.665 +	else
   1.666 +		{
   1.667 +		s->init_num+=i;
   1.668 +
   1.669 +		/* Check for error.  While there are recoverable errors,
   1.670 +		 * this function is not called when those must be expected;
   1.671 +		 * any error detected here is fatal. */
   1.672 +		if (s->init_num >= 3)
   1.673 +			{
   1.674 +			p=(unsigned char *)s->init_buf->data;
   1.675 +			if (p[0] == SSL2_MT_ERROR)
   1.676 +				{
   1.677 +				j=(p[1]<<8)|p[2];
   1.678 +				SSLerr((int)f,ssl_mt_error(j));
   1.679 +				s->init_num -= 3;
   1.680 +				if (s->init_num > 0)
   1.681 +					memmove(p, p+3, s->init_num);
   1.682 +				}
   1.683 +			}
   1.684 +
   1.685 +		/* If it's not an error message, we have some error anyway --
   1.686 +		 * the message was shorter than expected.  This too is treated
   1.687 +		 * as fatal (at least if SSL_get_error is asked for its opinion). */
   1.688 +		return(0);
   1.689 +		}
   1.690 +	}
   1.691 +
   1.692 +int ssl2_do_write(SSL *s)
   1.693 +	{
   1.694 +	int ret;
   1.695 +
   1.696 +	ret=ssl2_write(s,&s->init_buf->data[s->init_off],s->init_num);
   1.697 +	if (ret == s->init_num)
   1.698 +		{
   1.699 +		if (s->msg_callback)
   1.700 +			s->msg_callback(1, s->version, 0, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
   1.701 +		return(1);
   1.702 +		}
   1.703 +	if (ret < 0)
   1.704 +		return(-1);
   1.705 +	s->init_off+=ret;
   1.706 +	s->init_num-=ret;
   1.707 +	return(0);
   1.708 +	}
   1.709 +
   1.710 +static int ssl_mt_error(int n)
   1.711 +	{
   1.712 +	int ret;
   1.713 +
   1.714 +	switch (n)
   1.715 +		{
   1.716 +	case SSL2_PE_NO_CIPHER:
   1.717 +		ret=SSL_R_PEER_ERROR_NO_CIPHER;
   1.718 +		break;
   1.719 +	case SSL2_PE_NO_CERTIFICATE:
   1.720 +		ret=SSL_R_PEER_ERROR_NO_CERTIFICATE;
   1.721 +		break;
   1.722 +	case SSL2_PE_BAD_CERTIFICATE:
   1.723 +		ret=SSL_R_PEER_ERROR_CERTIFICATE;
   1.724 +		break;
   1.725 +	case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE:
   1.726 +		ret=SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
   1.727 +		break;
   1.728 +	default:
   1.729 +		ret=SSL_R_UNKNOWN_REMOTE_ERROR_TYPE;
   1.730 +		break;
   1.731 +		}
   1.732 +	return(ret);
   1.733 +	}
   1.734 +#else /* !OPENSSL_NO_SSL2 */
   1.735 +
   1.736 +# if PEDANTIC
   1.737 +static void *dummy=&dummy;
   1.738 +# endif
   1.739 +
   1.740 +#endif