Home | History | Annotate | Download | only in ssl
      1 /* ssl/s2_pkt.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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-2001 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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
    108  * Hudson (tjh (at) cryptsoft.com).
    109  *
    110  */
    111 
    112 #include "ssl_locl.h"
    113 #ifndef OPENSSL_NO_SSL2
    114 #include <stdio.h>
    115 #include <errno.h>
    116 #define USE_SOCKETS
    117 
    118 static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend);
    119 static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
    120 static int write_pending(SSL *s, const unsigned char *buf, unsigned int len);
    121 static int ssl_mt_error(int n);
    122 
    123 
    124 /* SSL 2.0 imlementation for SSL_read/SSL_peek -
    125  * This routine will return 0 to len bytes, decrypted etc if required.
    126  */
    127 static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
    128 	{
    129 	int n;
    130 	unsigned char mac[MAX_MAC_SIZE];
    131 	unsigned char *p;
    132 	int i;
    133 	int mac_size;
    134 
    135  ssl2_read_again:
    136 	if (SSL_in_init(s) && !s->in_handshake)
    137 		{
    138 		n=s->handshake_func(s);
    139 		if (n < 0) return(n);
    140 		if (n == 0)
    141 			{
    142 			SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_SSL_HANDSHAKE_FAILURE);
    143 			return(-1);
    144 			}
    145 		}
    146 
    147 	clear_sys_error();
    148 	s->rwstate=SSL_NOTHING;
    149 	if (len <= 0) return(len);
    150 
    151 	if (s->s2->ract_data_length != 0) /* read from buffer */
    152 		{
    153 		if (len > s->s2->ract_data_length)
    154 			n=s->s2->ract_data_length;
    155 		else
    156 			n=len;
    157 
    158 		memcpy(buf,s->s2->ract_data,(unsigned int)n);
    159 		if (!peek)
    160 			{
    161 			s->s2->ract_data_length-=n;
    162 			s->s2->ract_data+=n;
    163 			if (s->s2->ract_data_length == 0)
    164 				s->rstate=SSL_ST_READ_HEADER;
    165 			}
    166 
    167 		return(n);
    168 		}
    169 
    170 	/* s->s2->ract_data_length == 0
    171 	 *
    172 	 * Fill the buffer, then goto ssl2_read_again.
    173 	 */
    174 
    175 	if (s->rstate == SSL_ST_READ_HEADER)
    176 		{
    177 		if (s->first_packet)
    178 			{
    179 			n=read_n(s,5,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
    180 			if (n <= 0) return(n); /* error or non-blocking */
    181 			s->first_packet=0;
    182 			p=s->packet;
    183 			if (!((p[0] & 0x80) && (
    184 				(p[2] == SSL2_MT_CLIENT_HELLO) ||
    185 				(p[2] == SSL2_MT_SERVER_HELLO))))
    186 				{
    187 				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_NON_SSLV2_INITIAL_PACKET);
    188 				return(-1);
    189 				}
    190 			}
    191 		else
    192 			{
    193 			n=read_n(s,2,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
    194 			if (n <= 0) return(n); /* error or non-blocking */
    195 			}
    196 		/* part read stuff */
    197 
    198 		s->rstate=SSL_ST_READ_BODY;
    199 		p=s->packet;
    200 		/* Do header */
    201 		/*s->s2->padding=0;*/
    202 		s->s2->escape=0;
    203 		s->s2->rlength=(((unsigned int)p[0])<<8)|((unsigned int)p[1]);
    204 		if ((p[0] & TWO_BYTE_BIT))		/* Two byte header? */
    205 			{
    206 			s->s2->three_byte_header=0;
    207 			s->s2->rlength&=TWO_BYTE_MASK;
    208 			}
    209 		else
    210 			{
    211 			s->s2->three_byte_header=1;
    212 			s->s2->rlength&=THREE_BYTE_MASK;
    213 
    214 			/* security >s2->escape */
    215 			s->s2->escape=((p[0] & SEC_ESC_BIT))?1:0;
    216 			}
    217 		}
    218 
    219 	if (s->rstate == SSL_ST_READ_BODY)
    220 		{
    221 		n=s->s2->rlength+2+s->s2->three_byte_header;
    222 		if (n > (int)s->packet_length)
    223 			{
    224 			n-=s->packet_length;
    225 			i=read_n(s,(unsigned int)n,(unsigned int)n,1);
    226 			if (i <= 0) return(i); /* ERROR */
    227 			}
    228 
    229 		p= &(s->packet[2]);
    230 		s->rstate=SSL_ST_READ_HEADER;
    231 		if (s->s2->three_byte_header)
    232 			s->s2->padding= *(p++);
    233 		else	s->s2->padding=0;
    234 
    235 		/* Data portion */
    236 		if (s->s2->clear_text)
    237 			{
    238 			mac_size = 0;
    239 			s->s2->mac_data=p;
    240 			s->s2->ract_data=p;
    241 			if (s->s2->padding)
    242 				{
    243 				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
    244 				return(-1);
    245 				}
    246 			}
    247 		else
    248 			{
    249 			mac_size=EVP_MD_CTX_size(s->read_hash);
    250 			if (mac_size < 0)
    251 				return -1;
    252 			OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
    253 			s->s2->mac_data=p;
    254 			s->s2->ract_data= &p[mac_size];
    255 			if (s->s2->padding + mac_size > s->s2->rlength)
    256 				{
    257 				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
    258 				return(-1);
    259 				}
    260 			}
    261 
    262 		s->s2->ract_data_length=s->s2->rlength;
    263 		/* added a check for length > max_size in case
    264 		 * encryption was not turned on yet due to an error */
    265 		if ((!s->s2->clear_text) &&
    266 			(s->s2->rlength >= (unsigned int)mac_size))
    267 			{
    268 			ssl2_enc(s,0);
    269 			s->s2->ract_data_length-=mac_size;
    270 			ssl2_mac(s,mac,0);
    271 			s->s2->ract_data_length-=s->s2->padding;
    272 			if (	(CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) ||
    273 				(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
    274 				{
    275 				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
    276 				return(-1);
    277 				}
    278 			}
    279 		INC32(s->s2->read_sequence); /* expect next number */
    280 		/* s->s2->ract_data is now available for processing */
    281 
    282 		/* Possibly the packet that we just read had 0 actual data bytes.
    283 		 * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.)
    284 		 * In this case, returning 0 would be interpreted by the caller
    285 		 * as indicating EOF, so it's not a good idea.  Instead, we just
    286 		 * continue reading; thus ssl2_read_internal may have to process
    287 		 * multiple packets before it can return.
    288 		 *
    289 		 * [Note that using select() for blocking sockets *never* guarantees
    290 		 * that the next SSL_read will not block -- the available
    291 		 * data may contain incomplete packets, and except for SSL 2,
    292 		 * renegotiation can confuse things even more.] */
    293 
    294 		goto ssl2_read_again; /* This should really be
    295 		                       * "return ssl2_read(s,buf,len)",
    296 		                       * but that would allow for
    297 		                       * denial-of-service attacks if a
    298 		                       * C compiler is used that does not
    299 		                       * recognize end-recursion. */
    300 		}
    301 	else
    302 		{
    303 		SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_STATE);
    304 			return(-1);
    305 		}
    306 	}
    307 
    308 int ssl2_read(SSL *s, void *buf, int len)
    309 	{
    310 	return ssl2_read_internal(s, buf, len, 0);
    311 	}
    312 
    313 int ssl2_peek(SSL *s, void *buf, int len)
    314 	{
    315 	return ssl2_read_internal(s, buf, len, 1);
    316 	}
    317 
    318 static int read_n(SSL *s, unsigned int n, unsigned int max,
    319 	     unsigned int extend)
    320 	{
    321 	int i,off,newb;
    322 
    323 	/* if there is stuff still in the buffer from a previous read,
    324 	 * and there is more than we want, take some. */
    325 	if (s->s2->rbuf_left >= (int)n)
    326 		{
    327 		if (extend)
    328 			s->packet_length+=n;
    329 		else
    330 			{
    331 			s->packet= &(s->s2->rbuf[s->s2->rbuf_offs]);
    332 			s->packet_length=n;
    333 			}
    334 		s->s2->rbuf_left-=n;
    335 		s->s2->rbuf_offs+=n;
    336 		return(n);
    337 		}
    338 
    339 	if (!s->read_ahead) max=n;
    340 	if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2))
    341 		max=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2;
    342 
    343 
    344 	/* Else we want more than we have.
    345 	 * First, if there is some left or we want to extend */
    346 	off=0;
    347 	if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend))
    348 		{
    349 		newb=s->s2->rbuf_left;
    350 		if (extend)
    351 			{
    352 			off=s->packet_length;
    353 			if (s->packet != s->s2->rbuf)
    354 				memcpy(s->s2->rbuf,s->packet,
    355 					(unsigned int)newb+off);
    356 			}
    357 		else if (s->s2->rbuf_offs != 0)
    358 			{
    359 			memcpy(s->s2->rbuf,&(s->s2->rbuf[s->s2->rbuf_offs]),
    360 				(unsigned int)newb);
    361 			s->s2->rbuf_offs=0;
    362 			}
    363 		s->s2->rbuf_left=0;
    364 		}
    365 	else
    366 		newb=0;
    367 
    368 	/* off is the offset to start writing too.
    369 	 * r->s2->rbuf_offs is the 'unread data', now 0.
    370 	 * newb is the number of new bytes so far
    371 	 */
    372 	s->packet=s->s2->rbuf;
    373 	while (newb < (int)n)
    374 		{
    375 		clear_sys_error();
    376 		if (s->rbio != NULL)
    377 			{
    378 			s->rwstate=SSL_READING;
    379 			i=BIO_read(s->rbio,(char *)&(s->s2->rbuf[off+newb]),
    380 				max-newb);
    381 			}
    382 		else
    383 			{
    384 			SSLerr(SSL_F_READ_N,SSL_R_READ_BIO_NOT_SET);
    385 			i= -1;
    386 			}
    387 #ifdef PKT_DEBUG
    388 		if (s->debug & 0x01) sleep(1);
    389 #endif
    390 		if (i <= 0)
    391 			{
    392 			s->s2->rbuf_left+=newb;
    393 			return(i);
    394 			}
    395 		newb+=i;
    396 		}
    397 
    398 	/* record unread data */
    399 	if (newb > (int)n)
    400 		{
    401 		s->s2->rbuf_offs=n+off;
    402 		s->s2->rbuf_left=newb-n;
    403 		}
    404 	else
    405 		{
    406 		s->s2->rbuf_offs=0;
    407 		s->s2->rbuf_left=0;
    408 		}
    409 	if (extend)
    410 		s->packet_length+=n;
    411 	else
    412 		s->packet_length=n;
    413 	s->rwstate=SSL_NOTHING;
    414 	return(n);
    415 	}
    416 
    417 int ssl2_write(SSL *s, const void *_buf, int len)
    418 	{
    419 	const unsigned char *buf=_buf;
    420 	unsigned int n,tot;
    421 	int i;
    422 
    423 	if (SSL_in_init(s) && !s->in_handshake)
    424 		{
    425 		i=s->handshake_func(s);
    426 		if (i < 0) return(i);
    427 		if (i == 0)
    428 			{
    429 			SSLerr(SSL_F_SSL2_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE);
    430 			return(-1);
    431 			}
    432 		}
    433 
    434 	if (s->error)
    435 		{
    436 		ssl2_write_error(s);
    437 		if (s->error)
    438 			return(-1);
    439 		}
    440 
    441 	clear_sys_error();
    442 	s->rwstate=SSL_NOTHING;
    443 	if (len <= 0) return(len);
    444 
    445 	tot=s->s2->wnum;
    446 	s->s2->wnum=0;
    447 
    448 	n=(len-tot);
    449 	for (;;)
    450 		{
    451 		i=n_do_ssl_write(s,&(buf[tot]),n);
    452 		if (i <= 0)
    453 			{
    454 			s->s2->wnum=tot;
    455 			return(i);
    456 			}
    457 		if ((i == (int)n) ||
    458 			(s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))
    459 			{
    460 			return(tot+i);
    461 			}
    462 
    463 		n-=i;
    464 		tot+=i;
    465 		}
    466 	}
    467 
    468 static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
    469 	{
    470 	int i;
    471 
    472 	/* s->s2->wpend_len != 0 MUST be true. */
    473 
    474 	/* check that they have given us the same buffer to
    475 	 * write */
    476 	if ((s->s2->wpend_tot > (int)len) ||
    477 		((s->s2->wpend_buf != buf) &&
    478 		 !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
    479 		{
    480 		SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
    481 		return(-1);
    482 		}
    483 
    484 	for (;;)
    485 		{
    486 		clear_sys_error();
    487 		if (s->wbio != NULL)
    488 			{
    489 			s->rwstate=SSL_WRITING;
    490 			i=BIO_write(s->wbio,
    491 				(char *)&(s->s2->write_ptr[s->s2->wpend_off]),
    492 				(unsigned int)s->s2->wpend_len);
    493 			}
    494 		else
    495 			{
    496 			SSLerr(SSL_F_WRITE_PENDING,SSL_R_WRITE_BIO_NOT_SET);
    497 			i= -1;
    498 			}
    499 #ifdef PKT_DEBUG
    500 		if (s->debug & 0x01) sleep(1);
    501 #endif
    502 		if (i == s->s2->wpend_len)
    503 			{
    504 			s->s2->wpend_len=0;
    505 			s->rwstate=SSL_NOTHING;
    506 			return(s->s2->wpend_ret);
    507 			}
    508 		else if (i <= 0)
    509 			return(i);
    510 		s->s2->wpend_off+=i;
    511 		s->s2->wpend_len-=i;
    512 		}
    513 	}
    514 
    515 static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
    516 	{
    517 	unsigned int j,k,olen,p,bs;
    518 	int mac_size;
    519 	register unsigned char *pp;
    520 
    521 	olen=len;
    522 
    523 	/* first check if there is data from an encryption waiting to
    524 	 * be sent - it must be sent because the other end is waiting.
    525 	 * This will happen with non-blocking IO.  We print it and then
    526 	 * return.
    527 	 */
    528 	if (s->s2->wpend_len != 0) return(write_pending(s,buf,len));
    529 
    530 	/* set mac_size to mac size */
    531 	if (s->s2->clear_text)
    532 		mac_size=0;
    533 	else
    534 		{
    535 		mac_size=EVP_MD_CTX_size(s->write_hash);
    536 		if (mac_size < 0)
    537 			return -1;
    538 		}
    539 
    540 	/* lets set the pad p */
    541 	if (s->s2->clear_text)
    542 		{
    543 		if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
    544 			len=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
    545 		p=0;
    546 		s->s2->three_byte_header=0;
    547 		/* len=len; */
    548 		}
    549 	else
    550 		{
    551 		bs=EVP_CIPHER_CTX_block_size(s->enc_read_ctx);
    552 		j=len+mac_size;
    553 		/* Two-byte headers allow for a larger record length than
    554 		 * three-byte headers, but we can't use them if we need
    555 		 * padding or if we have to set the escape bit. */
    556 		if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) &&
    557 			(!s->s2->escape))
    558 			{
    559 			if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
    560 				j=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
    561 			/* set k to the max number of bytes with 2
    562 			 * byte header */
    563 			k=j-(j%bs);
    564 			/* how many data bytes? */
    565 			len=k-mac_size;
    566 			s->s2->three_byte_header=0;
    567 			p=0;
    568 			}
    569 		else if ((bs <= 1) && (!s->s2->escape))
    570 			{
    571 			/* j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus
    572 			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER */
    573 			s->s2->three_byte_header=0;
    574 			p=0;
    575 			}
    576 		else /* we may have to use a 3 byte header */
    577 			{
    578 			/* If s->s2->escape is not set, then
    579 			 * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus
    580 			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. */
    581 			p=(j%bs);
    582 			p=(p == 0)?0:(bs-p);
    583 			if (s->s2->escape)
    584 				{
    585 				s->s2->three_byte_header=1;
    586 				if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
    587 					j=SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER;
    588 				}
    589 			else
    590 				s->s2->three_byte_header=(p == 0)?0:1;
    591 			}
    592 		}
    593 
    594 	/* Now
    595 	 *      j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER
    596 	 * holds, and if s->s2->three_byte_header is set, then even
    597 	 *      j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER.
    598 	 */
    599 
    600 	/* mac_size is the number of MAC bytes
    601 	 * len is the number of data bytes we are going to send
    602 	 * p is the number of padding bytes
    603 	 * (if it is a two-byte header, then p == 0) */
    604 
    605 	s->s2->wlength=len;
    606 	s->s2->padding=p;
    607 	s->s2->mac_data= &(s->s2->wbuf[3]);
    608 	s->s2->wact_data= &(s->s2->wbuf[3+mac_size]);
    609 	/* we copy the data into s->s2->wbuf */
    610 	memcpy(s->s2->wact_data,buf,len);
    611 	if (p)
    612 		memset(&(s->s2->wact_data[len]),0,p); /* arbitrary padding */
    613 
    614 	if (!s->s2->clear_text)
    615 		{
    616 		s->s2->wact_data_length=len+p;
    617 		ssl2_mac(s,s->s2->mac_data,1);
    618 		s->s2->wlength+=p+mac_size;
    619 		ssl2_enc(s,1);
    620 		}
    621 
    622 	/* package up the header */
    623 	s->s2->wpend_len=s->s2->wlength;
    624 	if (s->s2->three_byte_header) /* 3 byte header */
    625 		{
    626 		pp=s->s2->mac_data;
    627 		pp-=3;
    628 		pp[0]=(s->s2->wlength>>8)&(THREE_BYTE_MASK>>8);
    629 		if (s->s2->escape) pp[0]|=SEC_ESC_BIT;
    630 		pp[1]=s->s2->wlength&0xff;
    631 		pp[2]=s->s2->padding;
    632 		s->s2->wpend_len+=3;
    633 		}
    634 	else
    635 		{
    636 		pp=s->s2->mac_data;
    637 		pp-=2;
    638 		pp[0]=((s->s2->wlength>>8)&(TWO_BYTE_MASK>>8))|TWO_BYTE_BIT;
    639 		pp[1]=s->s2->wlength&0xff;
    640 		s->s2->wpend_len+=2;
    641 		}
    642 	s->s2->write_ptr=pp;
    643 
    644 	INC32(s->s2->write_sequence); /* expect next number */
    645 
    646 	/* lets try to actually write the data */
    647 	s->s2->wpend_tot=olen;
    648 	s->s2->wpend_buf=buf;
    649 
    650 	s->s2->wpend_ret=len;
    651 
    652 	s->s2->wpend_off=0;
    653 	return(write_pending(s,buf,olen));
    654 	}
    655 
    656 int ssl2_part_read(SSL *s, unsigned long f, int i)
    657 	{
    658 	unsigned char *p;
    659 	int j;
    660 
    661 	if (i < 0)
    662 		{
    663 		/* ssl2_return_error(s); */
    664 		/* for non-blocking io,
    665 		 * this is not necessarily fatal */
    666 		return(i);
    667 		}
    668 	else
    669 		{
    670 		s->init_num+=i;
    671 
    672 		/* Check for error.  While there are recoverable errors,
    673 		 * this function is not called when those must be expected;
    674 		 * any error detected here is fatal. */
    675 		if (s->init_num >= 3)
    676 			{
    677 			p=(unsigned char *)s->init_buf->data;
    678 			if (p[0] == SSL2_MT_ERROR)
    679 				{
    680 				j=(p[1]<<8)|p[2];
    681 				SSLerr((int)f,ssl_mt_error(j));
    682 				s->init_num -= 3;
    683 				if (s->init_num > 0)
    684 					memmove(p, p+3, s->init_num);
    685 				}
    686 			}
    687 
    688 		/* If it's not an error message, we have some error anyway --
    689 		 * the message was shorter than expected.  This too is treated
    690 		 * as fatal (at least if SSL_get_error is asked for its opinion). */
    691 		return(0);
    692 		}
    693 	}
    694 
    695 int ssl2_do_write(SSL *s)
    696 	{
    697 	int ret;
    698 
    699 	ret=ssl2_write(s,&s->init_buf->data[s->init_off],s->init_num);
    700 	if (ret == s->init_num)
    701 		{
    702 		if (s->msg_callback)
    703 			s->msg_callback(1, s->version, 0, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
    704 		return(1);
    705 		}
    706 	if (ret < 0)
    707 		return(-1);
    708 	s->init_off+=ret;
    709 	s->init_num-=ret;
    710 	return(0);
    711 	}
    712 
    713 static int ssl_mt_error(int n)
    714 	{
    715 	int ret;
    716 
    717 	switch (n)
    718 		{
    719 	case SSL2_PE_NO_CIPHER:
    720 		ret=SSL_R_PEER_ERROR_NO_CIPHER;
    721 		break;
    722 	case SSL2_PE_NO_CERTIFICATE:
    723 		ret=SSL_R_PEER_ERROR_NO_CERTIFICATE;
    724 		break;
    725 	case SSL2_PE_BAD_CERTIFICATE:
    726 		ret=SSL_R_PEER_ERROR_CERTIFICATE;
    727 		break;
    728 	case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE:
    729 		ret=SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
    730 		break;
    731 	default:
    732 		ret=SSL_R_UNKNOWN_REMOTE_ERROR_TYPE;
    733 		break;
    734 		}
    735 	return(ret);
    736 	}
    737 #else /* !OPENSSL_NO_SSL2 */
    738 
    739 # if PEDANTIC
    740 static void *dummy=&dummy;
    741 # endif
    742 
    743 #endif
    744