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