155714Skris/* ssl/s2_pkt.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8296465Sdelphij * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296465Sdelphij * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22296465Sdelphij * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296465Sdelphij * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52296465Sdelphij * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5772616Skris */ 5872616Skris/* ==================================================================== 5989840Skris * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 6055949Skris * 6172616Skris * Redistribution and use in source and binary forms, with or without 6272616Skris * modification, are permitted provided that the following conditions 6372616Skris * are met: 6472616Skris * 6572616Skris * 1. Redistributions of source code must retain the above copyright 66296465Sdelphij * notice, this list of conditions and the following disclaimer. 6772616Skris * 6872616Skris * 2. Redistributions in binary form must reproduce the above copyright 6972616Skris * notice, this list of conditions and the following disclaimer in 7072616Skris * the documentation and/or other materials provided with the 7172616Skris * distribution. 7272616Skris * 7372616Skris * 3. All advertising materials mentioning features or use of this 7472616Skris * software must display the following acknowledgment: 7572616Skris * "This product includes software developed by the OpenSSL Project 7672616Skris * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 7772616Skris * 7872616Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 7972616Skris * endorse or promote products derived from this software without 8072616Skris * prior written permission. For written permission, please contact 8172616Skris * openssl-core@openssl.org. 8272616Skris * 8372616Skris * 5. Products derived from this software may not be called "OpenSSL" 8472616Skris * nor may "OpenSSL" appear in their names without prior written 8572616Skris * permission of the OpenSSL Project. 8672616Skris * 8772616Skris * 6. Redistributions of any form whatsoever must retain the following 8872616Skris * acknowledgment: 8972616Skris * "This product includes software developed by the OpenSSL Project 9072616Skris * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 9172616Skris * 9272616Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 9372616Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9472616Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 9572616Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 9672616Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 9772616Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 9872616Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 9972616Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10072616Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 10172616Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10272616Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 10372616Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 10472616Skris * ==================================================================== 10572616Skris * 10672616Skris * This product includes cryptographic software written by Eric Young 10772616Skris * (eay@cryptsoft.com). This product includes software written by Tim 10872616Skris * Hudson (tjh@cryptsoft.com). 10972616Skris * 11055714Skris */ 11155714Skris 11259194Skris#include "ssl_locl.h" 113110007Smarkm#ifndef OPENSSL_NO_SSL2 114296465Sdelphij# include <stdio.h> 115296465Sdelphij# include <errno.h> 116296465Sdelphij# define USE_SOCKETS 11755714Skris 118296465Sdelphijstatic int read_n(SSL *s, unsigned int n, unsigned int max, 119296465Sdelphij unsigned int extend); 12055714Skrisstatic int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); 12155714Skrisstatic int write_pending(SSL *s, const unsigned char *buf, unsigned int len); 12255714Skrisstatic int ssl_mt_error(int n); 12355714Skris 124296465Sdelphij/* 125296465Sdelphij * SSL 2.0 imlementation for SSL_read/SSL_peek - This routine will return 0 126296465Sdelphij * to len bytes, decrypted etc if required. 12755714Skris */ 12872616Skrisstatic int ssl2_read_internal(SSL *s, void *buf, int len, int peek) 129296465Sdelphij{ 130296465Sdelphij int n; 131296465Sdelphij unsigned char mac[MAX_MAC_SIZE]; 132296465Sdelphij unsigned char *p; 133296465Sdelphij int i; 134296465Sdelphij unsigned int mac_size; 13555714Skris 13672616Skris ssl2_read_again: 137296465Sdelphij if (SSL_in_init(s) && !s->in_handshake) { 138296465Sdelphij n = s->handshake_func(s); 139296465Sdelphij if (n < 0) 140296465Sdelphij return (n); 141296465Sdelphij if (n == 0) { 142296465Sdelphij SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_SSL_HANDSHAKE_FAILURE); 143296465Sdelphij return (-1); 144296465Sdelphij } 145296465Sdelphij } 14655714Skris 147296465Sdelphij clear_sys_error(); 148296465Sdelphij s->rwstate = SSL_NOTHING; 149296465Sdelphij if (len <= 0) 150296465Sdelphij return (len); 15155714Skris 152296465Sdelphij if (s->s2->ract_data_length != 0) { /* read from buffer */ 153296465Sdelphij if (len > s->s2->ract_data_length) 154296465Sdelphij n = s->s2->ract_data_length; 155296465Sdelphij else 156296465Sdelphij n = len; 15755714Skris 158296465Sdelphij memcpy(buf, s->s2->ract_data, (unsigned int)n); 159296465Sdelphij if (!peek) { 160296465Sdelphij s->s2->ract_data_length -= n; 161296465Sdelphij s->s2->ract_data += n; 162296465Sdelphij if (s->s2->ract_data_length == 0) 163296465Sdelphij s->rstate = SSL_ST_READ_HEADER; 164296465Sdelphij } 16572616Skris 166296465Sdelphij return (n); 167296465Sdelphij } 16855714Skris 169296465Sdelphij /* 170296465Sdelphij * s->s2->ract_data_length == 0 Fill the buffer, then goto 171296465Sdelphij * ssl2_read_again. 172296465Sdelphij */ 17372616Skris 174296465Sdelphij if (s->rstate == SSL_ST_READ_HEADER) { 175296465Sdelphij if (s->first_packet) { 176296465Sdelphij n = read_n(s, 5, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); 177296465Sdelphij if (n <= 0) 178296465Sdelphij return (n); /* error or non-blocking */ 179296465Sdelphij s->first_packet = 0; 180296465Sdelphij p = s->packet; 181296465Sdelphij if (!((p[0] & 0x80) && ((p[2] == SSL2_MT_CLIENT_HELLO) || 182296465Sdelphij (p[2] == SSL2_MT_SERVER_HELLO)))) { 183296465Sdelphij SSLerr(SSL_F_SSL2_READ_INTERNAL, 184296465Sdelphij SSL_R_NON_SSLV2_INITIAL_PACKET); 185296465Sdelphij return (-1); 186296465Sdelphij } 187296465Sdelphij } else { 188296465Sdelphij n = read_n(s, 2, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); 189296465Sdelphij if (n <= 0) 190296465Sdelphij return (n); /* error or non-blocking */ 191296465Sdelphij } 192296465Sdelphij /* part read stuff */ 19355714Skris 194296465Sdelphij s->rstate = SSL_ST_READ_BODY; 195296465Sdelphij p = s->packet; 196296465Sdelphij /* Do header */ 197296465Sdelphij /* 198296465Sdelphij * s->s2->padding=0; 199296465Sdelphij */ 200296465Sdelphij s->s2->escape = 0; 201296465Sdelphij s->s2->rlength = (((unsigned int)p[0]) << 8) | ((unsigned int)p[1]); 202296465Sdelphij if ((p[0] & TWO_BYTE_BIT)) { /* Two byte header? */ 203296465Sdelphij s->s2->three_byte_header = 0; 204296465Sdelphij s->s2->rlength &= TWO_BYTE_MASK; 205296465Sdelphij } else { 206296465Sdelphij s->s2->three_byte_header = 1; 207296465Sdelphij s->s2->rlength &= THREE_BYTE_MASK; 20855714Skris 209296465Sdelphij /* security >s2->escape */ 210296465Sdelphij s->s2->escape = ((p[0] & SEC_ESC_BIT)) ? 1 : 0; 211296465Sdelphij } 212296465Sdelphij } 21355714Skris 214296465Sdelphij if (s->rstate == SSL_ST_READ_BODY) { 215296465Sdelphij n = s->s2->rlength + 2 + s->s2->three_byte_header; 216296465Sdelphij if (n > (int)s->packet_length) { 217296465Sdelphij n -= s->packet_length; 218296465Sdelphij i = read_n(s, (unsigned int)n, (unsigned int)n, 1); 219296465Sdelphij if (i <= 0) 220296465Sdelphij return (i); /* ERROR */ 221296465Sdelphij } 22255714Skris 223296465Sdelphij p = &(s->packet[2]); 224296465Sdelphij s->rstate = SSL_ST_READ_HEADER; 225296465Sdelphij if (s->s2->three_byte_header) 226296465Sdelphij s->s2->padding = *(p++); 227296465Sdelphij else 228296465Sdelphij s->s2->padding = 0; 22955714Skris 230296465Sdelphij /* Data portion */ 231296465Sdelphij if (s->s2->clear_text) { 232296465Sdelphij mac_size = 0; 233296465Sdelphij s->s2->mac_data = p; 234296465Sdelphij s->s2->ract_data = p; 235296465Sdelphij if (s->s2->padding) { 236296465Sdelphij SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); 237296465Sdelphij return (-1); 238296465Sdelphij } 239296465Sdelphij } else { 240296465Sdelphij mac_size = EVP_MD_size(s->read_hash); 241296465Sdelphij OPENSSL_assert(mac_size <= MAX_MAC_SIZE); 242296465Sdelphij s->s2->mac_data = p; 243296465Sdelphij s->s2->ract_data = &p[mac_size]; 244296465Sdelphij if (s->s2->padding + mac_size > s->s2->rlength) { 245296465Sdelphij SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); 246296465Sdelphij return (-1); 247296465Sdelphij } 248296465Sdelphij } 24955714Skris 250296465Sdelphij s->s2->ract_data_length = s->s2->rlength; 251296465Sdelphij /* 252296465Sdelphij * added a check for length > max_size in case encryption was not 253296465Sdelphij * turned on yet due to an error 254296465Sdelphij */ 255296465Sdelphij if ((!s->s2->clear_text) && (s->s2->rlength >= mac_size)) { 256296465Sdelphij ssl2_enc(s, 0); 257296465Sdelphij s->s2->ract_data_length -= mac_size; 258296465Sdelphij ssl2_mac(s, mac, 0); 259296465Sdelphij s->s2->ract_data_length -= s->s2->padding; 260296465Sdelphij if ((CRYPTO_memcmp(mac, s->s2->mac_data, mac_size) != 0) || 261296465Sdelphij (s->s2->rlength % 262296465Sdelphij EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { 263296465Sdelphij SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_MAC_DECODE); 264296465Sdelphij return (-1); 265296465Sdelphij } 266296465Sdelphij } 267296465Sdelphij INC32(s->s2->read_sequence); /* expect next number */ 268296465Sdelphij /* s->s2->ract_data is now available for processing */ 26955714Skris 270296465Sdelphij /* 271296465Sdelphij * Possibly the packet that we just read had 0 actual data bytes. 272296465Sdelphij * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.) 273296465Sdelphij * In this case, returning 0 would be interpreted by the caller as 274296465Sdelphij * indicating EOF, so it's not a good idea. Instead, we just 275296465Sdelphij * continue reading; thus ssl2_read_internal may have to process 276296465Sdelphij * multiple packets before it can return. [Note that using select() 277296465Sdelphij * for blocking sockets *never* guarantees that the next SSL_read 278296465Sdelphij * will not block -- the available data may contain incomplete 279296465Sdelphij * packets, and except for SSL 2, renegotiation can confuse things 280296465Sdelphij * even more.] 281296465Sdelphij */ 28255714Skris 283296465Sdelphij goto ssl2_read_again; /* This should really be "return 284296465Sdelphij * ssl2_read(s,buf,len)", but that would 285296465Sdelphij * allow for denial-of-service attacks if a C 286296465Sdelphij * compiler is used that does not recognize 287296465Sdelphij * end-recursion. */ 288296465Sdelphij } else { 289296465Sdelphij SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_STATE); 290296465Sdelphij return (-1); 291296465Sdelphij } 292296465Sdelphij} 29355714Skris 29472616Skrisint ssl2_read(SSL *s, void *buf, int len) 295296465Sdelphij{ 296296465Sdelphij return ssl2_read_internal(s, buf, len, 0); 297296465Sdelphij} 29872616Skris 29976870Skrisint ssl2_peek(SSL *s, void *buf, int len) 300296465Sdelphij{ 301296465Sdelphij return ssl2_read_internal(s, buf, len, 1); 302296465Sdelphij} 30372616Skris 30455714Skrisstatic int read_n(SSL *s, unsigned int n, unsigned int max, 305296465Sdelphij unsigned int extend) 306296465Sdelphij{ 307296465Sdelphij int i, off, newb; 30855714Skris 309296465Sdelphij /* 310296465Sdelphij * if there is stuff still in the buffer from a previous read, and there 311296465Sdelphij * is more than we want, take some. 312296465Sdelphij */ 313296465Sdelphij if (s->s2->rbuf_left >= (int)n) { 314296465Sdelphij if (extend) 315296465Sdelphij s->packet_length += n; 316296465Sdelphij else { 317296465Sdelphij s->packet = &(s->s2->rbuf[s->s2->rbuf_offs]); 318296465Sdelphij s->packet_length = n; 319296465Sdelphij } 320296465Sdelphij s->s2->rbuf_left -= n; 321296465Sdelphij s->s2->rbuf_offs += n; 322296465Sdelphij return (n); 323296465Sdelphij } 32455714Skris 325296465Sdelphij if (!s->read_ahead) 326296465Sdelphij max = n; 327296465Sdelphij if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) 328296465Sdelphij max = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2; 32955714Skris 330296465Sdelphij /* 331296465Sdelphij * Else we want more than we have. First, if there is some left or we 332296465Sdelphij * want to extend 333296465Sdelphij */ 334296465Sdelphij off = 0; 335296465Sdelphij if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend)) { 336296465Sdelphij newb = s->s2->rbuf_left; 337296465Sdelphij if (extend) { 338296465Sdelphij off = s->packet_length; 339296465Sdelphij if (s->packet != s->s2->rbuf) 340296465Sdelphij memcpy(s->s2->rbuf, s->packet, (unsigned int)newb + off); 341296465Sdelphij } else if (s->s2->rbuf_offs != 0) { 342296465Sdelphij memcpy(s->s2->rbuf, &(s->s2->rbuf[s->s2->rbuf_offs]), 343296465Sdelphij (unsigned int)newb); 344296465Sdelphij s->s2->rbuf_offs = 0; 345296465Sdelphij } 346296465Sdelphij s->s2->rbuf_left = 0; 347296465Sdelphij } else 348296465Sdelphij newb = 0; 34955714Skris 350296465Sdelphij /* 351296465Sdelphij * off is the offset to start writing too. r->s2->rbuf_offs is the 352296465Sdelphij * 'unread data', now 0. newb is the number of new bytes so far 353296465Sdelphij */ 354296465Sdelphij s->packet = s->s2->rbuf; 355296465Sdelphij while (newb < (int)n) { 356296465Sdelphij clear_sys_error(); 357296465Sdelphij if (s->rbio != NULL) { 358296465Sdelphij s->rwstate = SSL_READING; 359296465Sdelphij i = BIO_read(s->rbio, (char *)&(s->s2->rbuf[off + newb]), 360296465Sdelphij max - newb); 361296465Sdelphij } else { 362296465Sdelphij SSLerr(SSL_F_READ_N, SSL_R_READ_BIO_NOT_SET); 363296465Sdelphij i = -1; 364296465Sdelphij } 365296465Sdelphij# ifdef PKT_DEBUG 366296465Sdelphij if (s->debug & 0x01) 367296465Sdelphij sleep(1); 368296465Sdelphij# endif 369296465Sdelphij if (i <= 0) { 370296465Sdelphij s->s2->rbuf_left += newb; 371296465Sdelphij return (i); 372296465Sdelphij } 373296465Sdelphij newb += i; 374296465Sdelphij } 37555714Skris 376296465Sdelphij /* record unread data */ 377296465Sdelphij if (newb > (int)n) { 378296465Sdelphij s->s2->rbuf_offs = n + off; 379296465Sdelphij s->s2->rbuf_left = newb - n; 380296465Sdelphij } else { 381296465Sdelphij s->s2->rbuf_offs = 0; 382296465Sdelphij s->s2->rbuf_left = 0; 383296465Sdelphij } 384296465Sdelphij if (extend) 385296465Sdelphij s->packet_length += n; 386296465Sdelphij else 387296465Sdelphij s->packet_length = n; 388296465Sdelphij s->rwstate = SSL_NOTHING; 389296465Sdelphij return (n); 390296465Sdelphij} 39155714Skris 39255714Skrisint ssl2_write(SSL *s, const void *_buf, int len) 393296465Sdelphij{ 394296465Sdelphij const unsigned char *buf = _buf; 395296465Sdelphij unsigned int n, tot; 396296465Sdelphij int i; 39755714Skris 398296465Sdelphij if (SSL_in_init(s) && !s->in_handshake) { 399296465Sdelphij i = s->handshake_func(s); 400296465Sdelphij if (i < 0) 401296465Sdelphij return (i); 402296465Sdelphij if (i == 0) { 403296465Sdelphij SSLerr(SSL_F_SSL2_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); 404296465Sdelphij return (-1); 405296465Sdelphij } 406296465Sdelphij } 40755714Skris 408296465Sdelphij if (s->error) { 409296465Sdelphij ssl2_write_error(s); 410296465Sdelphij if (s->error) 411296465Sdelphij return (-1); 412296465Sdelphij } 41355714Skris 414296465Sdelphij clear_sys_error(); 415296465Sdelphij s->rwstate = SSL_NOTHING; 416296465Sdelphij if (len <= 0) 417296465Sdelphij return (len); 41855714Skris 419296465Sdelphij tot = s->s2->wnum; 420296465Sdelphij s->s2->wnum = 0; 42155714Skris 422296465Sdelphij n = (len - tot); 423296465Sdelphij for (;;) { 424296465Sdelphij i = do_ssl_write(s, &(buf[tot]), n); 425296465Sdelphij if (i <= 0) { 426296465Sdelphij s->s2->wnum = tot; 427296465Sdelphij return (i); 428296465Sdelphij } 429296465Sdelphij if ((i == (int)n) || (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { 430296465Sdelphij return (tot + i); 431296465Sdelphij } 43255714Skris 433296465Sdelphij n -= i; 434296465Sdelphij tot += i; 435296465Sdelphij } 436296465Sdelphij} 437296465Sdelphij 43855714Skrisstatic int write_pending(SSL *s, const unsigned char *buf, unsigned int len) 439296465Sdelphij{ 440296465Sdelphij int i; 44155714Skris 442296465Sdelphij /* s->s2->wpend_len != 0 MUST be true. */ 44355714Skris 444296465Sdelphij /* 445296465Sdelphij * check that they have given us the same buffer to write 446296465Sdelphij */ 447296465Sdelphij if ((s->s2->wpend_tot > (int)len) || 448296465Sdelphij ((s->s2->wpend_buf != buf) && 449296465Sdelphij !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))) { 450296465Sdelphij SSLerr(SSL_F_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); 451296465Sdelphij return (-1); 452296465Sdelphij } 45355714Skris 454296465Sdelphij for (;;) { 455296465Sdelphij clear_sys_error(); 456296465Sdelphij if (s->wbio != NULL) { 457296465Sdelphij s->rwstate = SSL_WRITING; 458296465Sdelphij i = BIO_write(s->wbio, 459296465Sdelphij (char *)&(s->s2->write_ptr[s->s2->wpend_off]), 460296465Sdelphij (unsigned int)s->s2->wpend_len); 461296465Sdelphij } else { 462296465Sdelphij SSLerr(SSL_F_WRITE_PENDING, SSL_R_WRITE_BIO_NOT_SET); 463296465Sdelphij i = -1; 464296465Sdelphij } 465296465Sdelphij# ifdef PKT_DEBUG 466296465Sdelphij if (s->debug & 0x01) 467296465Sdelphij sleep(1); 468296465Sdelphij# endif 469296465Sdelphij if (i == s->s2->wpend_len) { 470296465Sdelphij s->s2->wpend_len = 0; 471296465Sdelphij s->rwstate = SSL_NOTHING; 472296465Sdelphij return (s->s2->wpend_ret); 473296465Sdelphij } else if (i <= 0) 474296465Sdelphij return (i); 475296465Sdelphij s->s2->wpend_off += i; 476296465Sdelphij s->s2->wpend_len -= i; 477296465Sdelphij } 478296465Sdelphij} 47955714Skris 48055714Skrisstatic int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) 481296465Sdelphij{ 482296465Sdelphij unsigned int j, k, olen, p, mac_size, bs; 483296465Sdelphij register unsigned char *pp; 48455714Skris 485296465Sdelphij olen = len; 48655714Skris 487296465Sdelphij /* 488296465Sdelphij * first check if there is data from an encryption waiting to be sent - 489296465Sdelphij * it must be sent because the other end is waiting. This will happen 490296465Sdelphij * with non-blocking IO. We print it and then return. 491296465Sdelphij */ 492296465Sdelphij if (s->s2->wpend_len != 0) 493296465Sdelphij return (write_pending(s, buf, len)); 49455714Skris 495296465Sdelphij /* set mac_size to mac size */ 496296465Sdelphij if (s->s2->clear_text) 497296465Sdelphij mac_size = 0; 498296465Sdelphij else 499296465Sdelphij mac_size = EVP_MD_size(s->write_hash); 50055714Skris 501296465Sdelphij /* lets set the pad p */ 502296465Sdelphij if (s->s2->clear_text) { 503296465Sdelphij if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) 504296465Sdelphij len = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; 505296465Sdelphij p = 0; 506296465Sdelphij s->s2->three_byte_header = 0; 507296465Sdelphij /* len=len; */ 508296465Sdelphij } else { 509296465Sdelphij bs = EVP_CIPHER_CTX_block_size(s->enc_read_ctx); 510296465Sdelphij j = len + mac_size; 511296465Sdelphij /* 512296465Sdelphij * Two-byte headers allow for a larger record length than three-byte 513296465Sdelphij * headers, but we can't use them if we need padding or if we have to 514296465Sdelphij * set the escape bit. 515296465Sdelphij */ 516296465Sdelphij if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) && (!s->s2->escape)) { 517296465Sdelphij if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) 518296465Sdelphij j = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; 519296465Sdelphij /* 520296465Sdelphij * set k to the max number of bytes with 2 byte header 521296465Sdelphij */ 522296465Sdelphij k = j - (j % bs); 523296465Sdelphij /* how many data bytes? */ 524296465Sdelphij len = k - mac_size; 525296465Sdelphij s->s2->three_byte_header = 0; 526296465Sdelphij p = 0; 527296465Sdelphij } else if ((bs <= 1) && (!s->s2->escape)) { 528296465Sdelphij /*- 529296465Sdelphij * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus 530296465Sdelphij * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 531296465Sdelphij */ 532296465Sdelphij s->s2->three_byte_header = 0; 533296465Sdelphij p = 0; 534296465Sdelphij } else { /* we may have to use a 3 byte header */ 53572616Skris 536296465Sdelphij /*- 537296465Sdelphij * If s->s2->escape is not set, then 538296465Sdelphij * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus 539296465Sdelphij * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. 540296465Sdelphij */ 541296465Sdelphij p = (j % bs); 542296465Sdelphij p = (p == 0) ? 0 : (bs - p); 543296465Sdelphij if (s->s2->escape) { 544296465Sdelphij s->s2->three_byte_header = 1; 545296465Sdelphij if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) 546296465Sdelphij j = SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER; 547296465Sdelphij } else 548296465Sdelphij s->s2->three_byte_header = (p == 0) ? 0 : 1; 549296465Sdelphij } 550296465Sdelphij } 55172616Skris 552296465Sdelphij /*- 553296465Sdelphij * Now 554296465Sdelphij * j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 555296465Sdelphij * holds, and if s->s2->three_byte_header is set, then even 556296465Sdelphij * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER. 557296465Sdelphij */ 55855714Skris 559296465Sdelphij /* 560296465Sdelphij * mac_size is the number of MAC bytes len is the number of data bytes we 561296465Sdelphij * are going to send p is the number of padding bytes (if it is a 562296465Sdelphij * two-byte header, then p == 0) 563296465Sdelphij */ 56455714Skris 565296465Sdelphij s->s2->wlength = len; 566296465Sdelphij s->s2->padding = p; 567296465Sdelphij s->s2->mac_data = &(s->s2->wbuf[3]); 568296465Sdelphij s->s2->wact_data = &(s->s2->wbuf[3 + mac_size]); 569296465Sdelphij /* we copy the data into s->s2->wbuf */ 570296465Sdelphij memcpy(s->s2->wact_data, buf, len); 571296465Sdelphij if (p) 572296465Sdelphij memset(&(s->s2->wact_data[len]), 0, p); /* arbitrary padding */ 57355714Skris 574296465Sdelphij if (!s->s2->clear_text) { 575296465Sdelphij s->s2->wact_data_length = len + p; 576296465Sdelphij ssl2_mac(s, s->s2->mac_data, 1); 577296465Sdelphij s->s2->wlength += p + mac_size; 578296465Sdelphij ssl2_enc(s, 1); 579296465Sdelphij } 58055714Skris 581296465Sdelphij /* package up the header */ 582296465Sdelphij s->s2->wpend_len = s->s2->wlength; 583296465Sdelphij if (s->s2->three_byte_header) { /* 3 byte header */ 584296465Sdelphij pp = s->s2->mac_data; 585296465Sdelphij pp -= 3; 586296465Sdelphij pp[0] = (s->s2->wlength >> 8) & (THREE_BYTE_MASK >> 8); 587296465Sdelphij if (s->s2->escape) 588296465Sdelphij pp[0] |= SEC_ESC_BIT; 589296465Sdelphij pp[1] = s->s2->wlength & 0xff; 590296465Sdelphij pp[2] = s->s2->padding; 591296465Sdelphij s->s2->wpend_len += 3; 592296465Sdelphij } else { 593296465Sdelphij pp = s->s2->mac_data; 594296465Sdelphij pp -= 2; 595296465Sdelphij pp[0] = ((s->s2->wlength >> 8) & (TWO_BYTE_MASK >> 8)) | TWO_BYTE_BIT; 596296465Sdelphij pp[1] = s->s2->wlength & 0xff; 597296465Sdelphij s->s2->wpend_len += 2; 598296465Sdelphij } 599296465Sdelphij s->s2->write_ptr = pp; 60055714Skris 601296465Sdelphij INC32(s->s2->write_sequence); /* expect next number */ 60255714Skris 603296465Sdelphij /* lets try to actually write the data */ 604296465Sdelphij s->s2->wpend_tot = olen; 605296465Sdelphij s->s2->wpend_buf = buf; 60655714Skris 607296465Sdelphij s->s2->wpend_ret = len; 608296465Sdelphij 609296465Sdelphij s->s2->wpend_off = 0; 610296465Sdelphij return (write_pending(s, buf, olen)); 611296465Sdelphij} 612296465Sdelphij 61355714Skrisint ssl2_part_read(SSL *s, unsigned long f, int i) 614296465Sdelphij{ 615296465Sdelphij unsigned char *p; 616296465Sdelphij int j; 61755714Skris 618296465Sdelphij if (i < 0) { 619296465Sdelphij /* ssl2_return_error(s); */ 620296465Sdelphij /* 621296465Sdelphij * for non-blocking io, this is not necessarily fatal 622296465Sdelphij */ 623296465Sdelphij return (i); 624296465Sdelphij } else { 625296465Sdelphij s->init_num += i; 62689840Skris 627296465Sdelphij /* 628296465Sdelphij * Check for error. While there are recoverable errors, this 629296465Sdelphij * function is not called when those must be expected; any error 630296465Sdelphij * detected here is fatal. 631296465Sdelphij */ 632296465Sdelphij if (s->init_num >= 3) { 633296465Sdelphij p = (unsigned char *)s->init_buf->data; 634296465Sdelphij if (p[0] == SSL2_MT_ERROR) { 635296465Sdelphij j = (p[1] << 8) | p[2]; 636296465Sdelphij SSLerr((int)f, ssl_mt_error(j)); 637296465Sdelphij s->init_num -= 3; 638296465Sdelphij if (s->init_num > 0) 639296465Sdelphij memmove(p, p + 3, s->init_num); 640296465Sdelphij } 641296465Sdelphij } 64289840Skris 643296465Sdelphij /* 644296465Sdelphij * If it's not an error message, we have some error anyway -- the 645296465Sdelphij * message was shorter than expected. This too is treated as fatal 646296465Sdelphij * (at least if SSL_get_error is asked for its opinion). 647296465Sdelphij */ 648296465Sdelphij return (0); 649296465Sdelphij } 650296465Sdelphij} 65155714Skris 65255714Skrisint ssl2_do_write(SSL *s) 653296465Sdelphij{ 654296465Sdelphij int ret; 65555714Skris 656296465Sdelphij ret = ssl2_write(s, &s->init_buf->data[s->init_off], s->init_num); 657296465Sdelphij if (ret == s->init_num) { 658296465Sdelphij if (s->msg_callback) 659296465Sdelphij s->msg_callback(1, s->version, 0, s->init_buf->data, 660296465Sdelphij (size_t)(s->init_off + s->init_num), s, 661296465Sdelphij s->msg_callback_arg); 662296465Sdelphij return (1); 663296465Sdelphij } 664296465Sdelphij if (ret < 0) 665296465Sdelphij return (-1); 666296465Sdelphij s->init_off += ret; 667296465Sdelphij s->init_num -= ret; 668296465Sdelphij return (0); 669296465Sdelphij} 67055714Skris 67155714Skrisstatic int ssl_mt_error(int n) 672296465Sdelphij{ 673296465Sdelphij int ret; 67455714Skris 675296465Sdelphij switch (n) { 676296465Sdelphij case SSL2_PE_NO_CIPHER: 677296465Sdelphij ret = SSL_R_PEER_ERROR_NO_CIPHER; 678296465Sdelphij break; 679296465Sdelphij case SSL2_PE_NO_CERTIFICATE: 680296465Sdelphij ret = SSL_R_PEER_ERROR_NO_CERTIFICATE; 681296465Sdelphij break; 682296465Sdelphij case SSL2_PE_BAD_CERTIFICATE: 683296465Sdelphij ret = SSL_R_PEER_ERROR_CERTIFICATE; 684296465Sdelphij break; 685296465Sdelphij case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE: 686296465Sdelphij ret = SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; 687296465Sdelphij break; 688296465Sdelphij default: 689296465Sdelphij ret = SSL_R_UNKNOWN_REMOTE_ERROR_TYPE; 690296465Sdelphij break; 691296465Sdelphij } 692296465Sdelphij return (ret); 693296465Sdelphij} 694296465Sdelphij#else /* !OPENSSL_NO_SSL2 */ 69555949Skris 69659194Skris# if PEDANTIC 697296465Sdelphijstatic void *dummy = &dummy; 69859194Skris# endif 69959194Skris 70055949Skris#endif 701