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 (	(memcmp(mac,s->s2->mac_data,
    273 				(unsigned int)mac_size) != 0) ||
    274 				(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
    275 				{
    276 				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
    277 				return(-1);
    278 				}
    279 			}
    280 		INC32(s->s2->read_sequence); /* expect next number */
    281 		/* s->s2->ract_data is now available for processing */
    282 
    283 		/* Possibly the packet that we just read had 0 actual data bytes.
    284 		 * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.)
    285 		 * In this case, returning 0 would be interpreted by the caller
    286 		 * as indicating EOF, so it's not a good idea.  Instead, we just
    287 		 * continue reading; thus ssl2_read_internal may have to process
    288 		 * multiple packets before it can return.
    289 		 *
    290 		 * [Note that using select() for blocking sockets *never* guarantees
    291 		 * that the next SSL_read will not block -- the available
    292 		 * data may contain incomplete packets, and except for SSL 2,
    293 		 * renegotiation can confuse things even more.] */
    294 
    295 		goto ssl2_read_again; /* This should really be
    296 		                       * "return ssl2_read(s,buf,len)",
    297 		                       * but that would allow for
    298 		                       * denial-of-service attacks if a
    299 		                       * C compiler is used that does not
    300 		                       * recognize end-recursion. */
    301 		}
    302 	else
    303 		{
    304 		SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_STATE);
    305 			return(-1);
    306 		}
    307 	}
    308 
    309 int ssl2_read(SSL *s, void *buf, int len)
    310 	{
    311 	return ssl2_read_internal(s, buf, len, 0);
    312 	}
    313 
    314 int ssl2_peek(SSL *s, void *buf, int len)
    315 	{
    316 	return ssl2_read_internal(s, buf, len, 1);
    317 	}
    318 
    319 static int read_n(SSL *s, unsigned int n, unsigned int max,
    320 	     unsigned int extend)
    321 	{
    322 	int i,off,newb;
    323 
    324 	/* if there is stuff still in the buffer from a previous read,
    325 	 * and there is more than we want, take some. */
    326 	if (s->s2->rbuf_left >= (int)n)
    327 		{
    328 		if (extend)
    329 			s->packet_length+=n;
    330 		else
    331 			{
    332 			s->packet= &(s->s2->rbuf[s->s2->rbuf_offs]);
    333 			s->packet_length=n;
    334 			}
    335 		s->s2->rbuf_left-=n;
    336 		s->s2->rbuf_offs+=n;
    337 		return(n);
    338 		}
    339 
    340 	if (!s->read_ahead) max=n;
    341 	if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2))
    342 		max=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2;
    343 
    344 
    345 	/* Else we want more than we have.
    346 	 * First, if there is some left or we want to extend */
    347 	off=0;
    348 	if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend))
    349 		{
    350 		newb=s->s2->rbuf_left;
    351 		if (extend)
    352 			{
    353 			off=s->packet_length;
    354 			if (s->packet != s->s2->rbuf)
    355 				memcpy(s->s2->rbuf,s->packet,
    356 					(unsigned int)newb+off);
    357 			}
    358 		else if (s->s2->rbuf_offs != 0)
    359 			{
    360 			memcpy(s->s2->rbuf,&(s->s2->rbuf[s->s2->rbuf_offs]),
    361 				(unsigned int)newb);
    362 			s->s2->rbuf_offs=0;
    363 			}
    364 		s->s2->rbuf_left=0;
    365 		}
    366 	else
    367 		newb=0;
    368 
    369 	/* off is the offset to start writing too.
    370 	 * r->s2->rbuf_offs is the 'unread data', now 0.
    371 	 * newb is the number of new bytes so far
    372 	 */
    373 	s->packet=s->s2->rbuf;
    374 	while (newb < (int)n)
    375 		{
    376 		clear_sys_error();
    377 		if (s->rbio != NULL)
    378 			{
    379 			s->rwstate=SSL_READING;
    380 			i=BIO_read(s->rbio,(char *)&(s->s2->rbuf[off+newb]),
    381 				max-newb);
    382 			}
    383 		else
    384 			{
    385 			SSLerr(SSL_F_READ_N,SSL_R_READ_BIO_NOT_SET);
    386 			i= -1;
    387 			}
    388 #ifdef PKT_DEBUG
    389 		if (s->debug & 0x01) sleep(1);
    390 #endif
    391 		if (i <= 0)
    392 			{
    393 			s->s2->rbuf_left+=newb;
    394 			return(i);
    395 			}
    396 		newb+=i;
    397 		}
    398 
    399 	/* record unread data */
    400 	if (newb > (int)n)
    401 		{
    402 		s->s2->rbuf_offs=n+off;
    403 		s->s2->rbuf_left=newb-n;
    404 		}
    405 	else
    406 		{
    407 		s->s2->rbuf_offs=0;
    408 		s->s2->rbuf_left=0;
    409 		}
    410 	if (extend)
    411 		s->packet_length+=n;
    412 	else
    413 		s->packet_length=n;
    414 	s->rwstate=SSL_NOTHING;
    415 	return(n);
    416 	}
    417 
    418 int ssl2_write(SSL *s, const void *_buf, int len)
    419 	{
    420 	const unsigned char *buf=_buf;
    421 	unsigned int n,tot;
    422 	int i;
    423 
    424 	if (SSL_in_init(s) && !s->in_handshake)
    425 		{
    426 		i=s->handshake_func(s);
    427 		if (i < 0) return(i);
    428 		if (i == 0)
    429 			{
    430 			SSLerr(SSL_F_SSL2_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE);
    431 			return(-1);
    432 			}
    433 		}
    434 
    435 	if (s->error)
    436 		{
    437 		ssl2_write_error(s);
    438 		if (s->error)
    439 			return(-1);
    440 		}
    441 
    442 	clear_sys_error();
    443 	s->rwstate=SSL_NOTHING;
    444 	if (len <= 0) return(len);
    445 
    446 	tot=s->s2->wnum;
    447 	s->s2->wnum=0;
    448 
    449 	n=(len-tot);
    450 	for (;;)
    451 		{
    452 		i=n_do_ssl_write(s,&(buf[tot]),n);
    453 		if (i <= 0)
    454 			{
    455 			s->s2->wnum=tot;
    456 			return(i);
    457 			}
    458 		if ((i == (int)n) ||
    459 			(s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))
    460 			{
    461 			return(tot+i);
    462 			}
    463 
    464 		n-=i;
    465 		tot+=i;
    466 		}
    467 	}
    468 
    469 static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
    470 	{
    471 	int i;
    472 
    473 	/* s->s2->wpend_len != 0 MUST be true. */
    474 
    475 	/* check that they have given us the same buffer to
    476 	 * write */
    477 	if ((s->s2->wpend_tot > (int)len) ||
    478 		((s->s2->wpend_buf != buf) &&
    479 		 !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
    480 		{
    481 		SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
    482 		return(-1);
    483 		}
    484 
    485 	for (;;)
    486 		{
    487 		clear_sys_error();
    488 		if (s->wbio != NULL)
    489 			{
    490 			s->rwstate=SSL_WRITING;
    491 			i=BIO_write(s->wbio,
    492 				(char *)&(s->s2->write_ptr[s->s2->wpend_off]),
    493 				(unsigned int)s->s2->wpend_len);
    494 			}
    495 		else
    496 			{
    497 			SSLerr(SSL_F_WRITE_PENDING,SSL_R_WRITE_BIO_NOT_SET);
    498 			i= -1;
    499 			}
    500 #ifdef PKT_DEBUG
    501 		if (s->debug & 0x01) sleep(1);
    502 #endif
    503 		if (i == s->s2->wpend_len)
    504 			{
    505 			s->s2->wpend_len=0;
    506 			s->rwstate=SSL_NOTHING;
    507 			return(s->s2->wpend_ret);
    508 			}
    509 		else if (i <= 0)
    510 			return(i);
    511 		s->s2->wpend_off+=i;
    512 		s->s2->wpend_len-=i;
    513 		}
    514 	}
    515 
    516 static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
    517 	{
    518 	unsigned int j,k,olen,p,bs;
    519 	int mac_size;
    520 	register unsigned char *pp;
    521 
    522 	olen=len;
    523 
    524 	/* first check if there is data from an encryption waiting to
    525 	 * be sent - it must be sent because the other end is waiting.
    526 	 * This will happen with non-blocking IO.  We print it and then
    527 	 * return.
    528 	 */
    529 	if (s->s2->wpend_len != 0) return(write_pending(s,buf,len));
    530 
    531 	/* set mac_size to mac size */
    532 	if (s->s2->clear_text)
    533 		mac_size=0;
    534 	else
    535 		{
    536 		mac_size=EVP_MD_CTX_size(s->write_hash);
    537 		if (mac_size < 0)
    538 			return -1;
    539 		}
    540 
    541 	/* lets set the pad p */
    542 	if (s->s2->clear_text)
    543 		{
    544 		if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
    545 			len=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
    546 		p=0;
    547 		s->s2->three_byte_header=0;
    548 		/* len=len; */
    549 		}
    550 	else
    551 		{
    552 		bs=EVP_CIPHER_CTX_block_size(s->enc_read_ctx);
    553 		j=len+mac_size;
    554 		/* Two-byte headers allow for a larger record length than
    555 		 * three-byte headers, but we can't use them if we need
    556 		 * padding or if we have to set the escape bit. */
    557 		if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) &&
    558 			(!s->s2->escape))
    559 			{
    560 			if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
    561 				j=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
    562 			/* set k to the max number of bytes with 2
    563 			 * byte header */
    564 			k=j-(j%bs);
    565 			/* how many data bytes? */
    566 			len=k-mac_size;
    567 			s->s2->three_byte_header=0;
    568 			p=0;
    569 			}
    570 		else if ((bs <= 1) && (!s->s2->escape))
    571 			{
    572 			/* j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus
    573 			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER */
    574 			s->s2->three_byte_header=0;
    575 			p=0;
    576 			}
    577 		else /* we may have to use a 3 byte header */
    578 			{
    579 			/* If s->s2->escape is not set, then
    580 			 * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus
    581 			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. */
    582 			p=(j%bs);
    583 			p=(p == 0)?0:(bs-p);
    584 			if (s->s2->escape)
    585 				{
    586 				s->s2->three_byte_header=1;
    587 				if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
    588 					j=SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER;
    589 				}
    590 			else
    591 				s->s2->three_byte_header=(p == 0)?0:1;
    592 			}
    593 		}
    594 
    595 	/* Now
    596 	 *      j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER
    597 	 * holds, and if s->s2->three_byte_header is set, then even
    598 	 *      j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER.
    599 	 */
    600 
    601 	/* mac_size is the number of MAC bytes
    602 	 * len is the number of data bytes we are going to send
    603 	 * p is the number of padding bytes
    604 	 * (if it is a two-byte header, then p == 0) */
    605 
    606 	s->s2->wlength=len;
    607 	s->s2->padding=p;
    608 	s->s2->mac_data= &(s->s2->wbuf[3]);
    609 	s->s2->wact_data= &(s->s2->wbuf[3+mac_size]);
    610 	/* we copy the data into s->s2->wbuf */
    611 	memcpy(s->s2->wact_data,buf,len);
    612 	if (p)
    613 		memset(&(s->s2->wact_data[len]),0,p); /* arbitrary padding */
    614 
    615 	if (!s->s2->clear_text)
    616 		{
    617 		s->s2->wact_data_length=len+p;
    618 		ssl2_mac(s,s->s2->mac_data,1);
    619 		s->s2->wlength+=p+mac_size;
    620 		ssl2_enc(s,1);
    621 		}
    622 
    623 	/* package up the header */
    624 	s->s2->wpend_len=s->s2->wlength;
    625 	if (s->s2->three_byte_header) /* 3 byte header */
    626 		{
    627 		pp=s->s2->mac_data;
    628 		pp-=3;
    629 		pp[0]=(s->s2->wlength>>8)&(THREE_BYTE_MASK>>8);
    630 		if (s->s2->escape) pp[0]|=SEC_ESC_BIT;
    631 		pp[1]=s->s2->wlength&0xff;
    632 		pp[2]=s->s2->padding;
    633 		s->s2->wpend_len+=3;
    634 		}
    635 	else
    636 		{
    637 		pp=s->s2->mac_data;
    638 		pp-=2;
    639 		pp[0]=((s->s2->wlength>>8)&(TWO_BYTE_MASK>>8))|TWO_BYTE_BIT;
    640 		pp[1]=s->s2->wlength&0xff;
    641 		s->s2->wpend_len+=2;
    642 		}
    643 	s->s2->write_ptr=pp;
    644 
    645 	INC32(s->s2->write_sequence); /* expect next number */
    646 
    647 	/* lets try to actually write the data */
    648 	s->s2->wpend_tot=olen;
    649 	s->s2->wpend_buf=buf;
    650 
    651 	s->s2->wpend_ret=len;
    652 
    653 	s->s2->wpend_off=0;
    654 	return(write_pending(s,buf,olen));
    655 	}
    656 
    657 int ssl2_part_read(SSL *s, unsigned long f, int i)
    658 	{
    659 	unsigned char *p;
    660 	int j;
    661 
    662 	if (i < 0)
    663 		{
    664 		/* ssl2_return_error(s); */
    665 		/* for non-blocking io,
    666 		 * this is not necessarily fatal */
    667 		return(i);
    668 		}
    669 	else
    670 		{
    671 		s->init_num+=i;
    672 
    673 		/* Check for error.  While there are recoverable errors,
    674 		 * this function is not called when those must be expected;
    675 		 * any error detected here is fatal. */
    676 		if (s->init_num >= 3)
    677 			{
    678 			p=(unsigned char *)s->init_buf->data;
    679 			if (p[0] == SSL2_MT_ERROR)
    680 				{
    681 				j=(p[1]<<8)|p[2];
    682 				SSLerr((int)f,ssl_mt_error(j));
    683 				s->init_num -= 3;
    684 				if (s->init_num > 0)
    685 					memmove(p, p+3, s->init_num);
    686 				}
    687 			}
    688 
    689 		/* If it's not an error message, we have some error anyway --
    690 		 * the message was shorter than expected.  This too is treated
    691 		 * as fatal (at least if SSL_get_error is asked for its opinion). */
    692 		return(0);
    693 		}
    694 	}
    695 
    696 int ssl2_do_write(SSL *s)
    697 	{
    698 	int ret;
    699 
    700 	ret=ssl2_write(s,&s->init_buf->data[s->init_off],s->init_num);
    701 	if (ret == s->init_num)
    702 		{
    703 		if (s->msg_callback)
    704 			s->msg_callback(1, s->version, 0, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
    705 		return(1);
    706 		}
    707 	if (ret < 0)
    708 		return(-1);
    709 	s->init_off+=ret;
    710 	s->init_num-=ret;
    711 	return(0);
    712 	}
    713 
    714 static int ssl_mt_error(int n)
    715 	{
    716 	int ret;
    717 
    718 	switch (n)
    719 		{
    720 	case SSL2_PE_NO_CIPHER:
    721 		ret=SSL_R_PEER_ERROR_NO_CIPHER;
    722 		break;
    723 	case SSL2_PE_NO_CERTIFICATE:
    724 		ret=SSL_R_PEER_ERROR_NO_CERTIFICATE;
    725 		break;
    726 	case SSL2_PE_BAD_CERTIFICATE:
    727 		ret=SSL_R_PEER_ERROR_CERTIFICATE;
    728 		break;
    729 	case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE:
    730 		ret=SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
    731 		break;
    732 	default:
    733 		ret=SSL_R_UNKNOWN_REMOTE_ERROR_TYPE;
    734 		break;
    735 		}
    736 	return(ret);
    737 	}
    738 #else /* !OPENSSL_NO_SSL2 */
    739 
    740 # if PEDANTIC
    741 static void *dummy=&dummy;
    742 # endif
    743 
    744 #endif
    745