1 /* ssl/s2_pkt.c */
   2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
   3  * All rights reserved.
   4  *
   5  * This package is an SSL implementation written
   6  * by Eric Young (eay@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@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@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@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@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@cryptsoft.com).  This product includes software written by Tim
 108  * Hudson (tjh@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