X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs2_pkt.c;h=8bb6ab8baa33501dcd6f0991d53ad80b3d9361aa;hp=d2dbf348caf1888c5bfeeb3a8c238b03882d3034;hb=daddd9a950e491c31f9500d5e570bc7eb96b2823;hpb=bc36ee6227517edae802bcb0da68d4f04fe1fb5e diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c index d2dbf348ca..8bb6ab8baa 100644 --- a/ssl/s2_pkt.c +++ b/ssl/s2_pkt.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -116,7 +116,7 @@ #define USE_SOCKETS static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend); -static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); static int write_pending(SSL *s, const unsigned char *buf, unsigned int len); static int ssl_mt_error(int n); @@ -130,7 +130,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) unsigned char mac[MAX_MAC_SIZE]; unsigned char *p; int i; - unsigned int mac_size=0; + int mac_size; ssl2_read_again: if (SSL_in_init(s) && !s->in_handshake) @@ -235,31 +235,41 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) /* Data portion */ if (s->s2->clear_text) { + mac_size = 0; s->s2->mac_data=p; s->s2->ract_data=p; - s->s2->pad_data=NULL; + if (s->s2->padding) + { + SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING); + return(-1); + } } else { - mac_size=EVP_MD_size(s->read_hash); + mac_size=EVP_MD_CTX_size(s->read_hash); + if (mac_size < 0) + return -1; + OPENSSL_assert(mac_size <= MAX_MAC_SIZE); s->s2->mac_data=p; s->s2->ract_data= &p[mac_size]; - s->s2->pad_data= &p[mac_size+ - s->s2->rlength-s->s2->padding]; + if (s->s2->padding + mac_size > s->s2->rlength) + { + SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING); + return(-1); + } } s->s2->ract_data_length=s->s2->rlength; /* added a check for length > max_size in case * encryption was not turned on yet due to an error */ if ((!s->s2->clear_text) && - (s->s2->rlength >= mac_size)) + (s->s2->rlength >= (unsigned int)mac_size)) { ssl2_enc(s,0); s->s2->ract_data_length-=mac_size; ssl2_mac(s,mac,0); s->s2->ract_data_length-=s->s2->padding; - if ( (memcmp(mac,s->s2->mac_data, - (unsigned int)mac_size) != 0) || + if ( (CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) || (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE); @@ -300,7 +310,7 @@ int ssl2_read(SSL *s, void *buf, int len) return ssl2_read_internal(s, buf, len, 0); } -int ssl2_peek(SSL *s, char *buf, int len) +int ssl2_peek(SSL *s, void *buf, int len) { return ssl2_read_internal(s, buf, len, 1); } @@ -438,7 +448,7 @@ int ssl2_write(SSL *s, const void *_buf, int len) n=(len-tot); for (;;) { - i=do_ssl_write(s,&(buf[tot]),n); + i=n_do_ssl_write(s,&(buf[tot]),n); if (i <= 0) { s->s2->wnum=tot; @@ -502,9 +512,10 @@ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) } } -static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) { - unsigned int j,k,olen,p,mac_size,bs; + unsigned int j,k,olen,p,bs; + int mac_size; register unsigned char *pp; olen=len; @@ -520,7 +531,11 @@ static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) if (s->s2->clear_text) mac_size=0; else - mac_size=EVP_MD_size(s->write_hash); + { + mac_size=EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + return -1; + } /* lets set the pad p */ if (s->s2->clear_text) @@ -593,10 +608,8 @@ static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) s->s2->wact_data= &(s->s2->wbuf[3+mac_size]); /* we copy the data into s->s2->wbuf */ memcpy(s->s2->wact_data,buf,len); -#ifdef PURIFY if (p) - memset(&(s->s2->wact_data[len]),0,p); -#endif + memset(&(s->s2->wact_data[len]),0,p); /* arbitrary padding */ if (!s->s2->clear_text) { @@ -645,27 +658,36 @@ int ssl2_part_read(SSL *s, unsigned long f, int i) unsigned char *p; int j; - /* check for error */ - if ((s->init_num == 0) && (i >= 3)) - { - p=(unsigned char *)s->init_buf->data; - if (p[0] == SSL2_MT_ERROR) - { - j=(p[1]<<8)|p[2]; - SSLerr((int)f,ssl_mt_error(j)); - } - } - if (i < 0) { /* ssl2_return_error(s); */ /* for non-blocking io, - * this is not fatal */ + * this is not necessarily fatal */ return(i); } else { s->init_num+=i; + + /* Check for error. While there are recoverable errors, + * this function is not called when those must be expected; + * any error detected here is fatal. */ + if (s->init_num >= 3) + { + p=(unsigned char *)s->init_buf->data; + if (p[0] == SSL2_MT_ERROR) + { + j=(p[1]<<8)|p[2]; + SSLerr((int)f,ssl_mt_error(j)); + s->init_num -= 3; + if (s->init_num > 0) + memmove(p, p+3, s->init_num); + } + } + + /* If it's not an error message, we have some error anyway -- + * the message was shorter than expected. This too is treated + * as fatal (at least if SSL_get_error is asked for its opinion). */ return(0); } } @@ -676,7 +698,11 @@ int ssl2_do_write(SSL *s) ret=ssl2_write(s,&s->init_buf->data[s->init_off],s->init_num); if (ret == s->init_num) + { + if (s->msg_callback) + s->msg_callback(1, s->version, 0, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg); return(1); + } if (ret < 0) return(-1); s->init_off+=ret;