From c1fb6557e5697d630bf7354083fb2ada00502857 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 17 Apr 2002 07:02:47 +0000 Subject: [PATCH] Merge in the latest changes from 0.9.6d-stable. --- CHANGES | 24 +++++++++ NEWS | 5 ++ apps/smime.c | 4 +- crypto/evp/encode.c | 7 +++ crypto/objects/obj_dat.c | 2 + doc/crypto/BN_bn2bin.pod | 2 +- doc/crypto/RSA_generate_key.pod | 2 +- shlib/Makefile.hpux10-cc | 27 ++-------- shlib/hpux10-cc.sh | 18 ++++--- ssl/s3_both.c | 18 ++++--- ssl/s3_enc.c | 65 ++++++++++++++++++++++- ssl/s3_lib.c | 18 ++++--- ssl/s3_pkt.c | 93 +++++++++++++++++++++++++-------- ssl/s3_srvr.c | 11 +++- ssl/ssl3.h | 71 +++++++++++++++++++++++-- ssl/t1_enc.c | 61 +++++++++++++++++++++ 16 files changed, 349 insertions(+), 79 deletions(-) diff --git a/CHANGES b/CHANGES index 35b77ba297..5a0e1ec76b 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,30 @@ Changes between 0.9.6c and 0.9.6d [XX xxx XXXX] + *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines: + an end-of-file condition would erronously be flagged, when the CRLF + was just at the end of a processed block. The bug was discovered when + processing data through a buffering memory BIO handing the data to a + BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov + and Nedelcho Stanev. + [Lutz Jaenicke] + + *) Implement a countermeasure against a vulnerability recently found + in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment + before application data chunks to avoid the use of known IVs + with data potentially chosen by the attacker. + [Bodo Moeller] + + *) Fix length checks in ssl3_get_client_hello(). + [Bodo Moeller] + + *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently + to prevent ssl3_read_internal() from incorrectly assuming that + ssl3_read_bytes() found application data while handshake + processing was enabled when in fact s->s3->in_read_app_data was + merely automatically cleared during the initial handshake. + [Bodo Moeller; problem pointed out by Arne Ansper ] + *) Fix object definitions for Private and Enterprise: they were not recognized in their shortname (=lowercase) representation. Extend obj_dat.pl to issue an error when using undefined keywords instead diff --git a/NEWS b/NEWS index 87728bb1c0..ca343e652f 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,11 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d: + + o Various SSL/TLS library bugfixes. + o Fix DH parameter generation for 'non-standard' generators. + Changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c: o Various SSL/TLS library bugfixes. diff --git a/apps/smime.c b/apps/smime.c index 7bf71ef868..61029a475d 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -481,9 +481,9 @@ int MAIN(int argc, char **argv) } else if(operation == SMIME_VERIFY) { STACK_OF(X509) *signers; if(PKCS7_verify(p7, other, store, indata, out, flags)) { - BIO_printf(bio_err, "Verification Successful\n"); + BIO_printf(bio_err, "Verification successful\n"); } else { - BIO_printf(bio_err, "Verification Failure\n"); + BIO_printf(bio_err, "Verification failure\n"); goto end; } signers = PKCS7_get0_signers(p7, other, flags); diff --git a/crypto/evp/encode.c b/crypto/evp/encode.c index 6ff9c1783c..12c6379df1 100644 --- a/crypto/evp/encode.c +++ b/crypto/evp/encode.c @@ -277,6 +277,13 @@ int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, eof++; } + if (v == B64_CR) + { + ln = 0; + if (exp_nl) + continue; + } + /* eoln */ if (v == B64_EOLN) { diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index 4b1bb9583a..4d82378b9d 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -645,6 +645,8 @@ int OBJ_create(char *oid, char *sn, char *ln) return(0); } i=a2d_ASN1_OBJECT(buf,i,oid,-1); + if (i == 0) + goto err; op=(ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1),buf,i,sn,ln); if (op == NULL) goto err; diff --git a/doc/crypto/BN_bn2bin.pod b/doc/crypto/BN_bn2bin.pod index c12af9c9f9..b62d1af0ff 100644 --- a/doc/crypto/BN_bn2bin.pod +++ b/doc/crypto/BN_bn2bin.pod @@ -49,7 +49,7 @@ with a leading '-' for negative numbers, to the B or B B. BN_bn2mpi() and BN_mpi2bn() convert Bs from and to a format -that consists of the number's length in bytes represented as a 3-byte +that consists of the number's length in bytes represented as a 4-byte big-endian number, and the number itself in big-endian format, where the most significant bit signals a negative number (the representation of numbers with the MSB set is prefixed with null byte). diff --git a/doc/crypto/RSA_generate_key.pod b/doc/crypto/RSA_generate_key.pod index fdaddbcb13..8714f7179d 100644 --- a/doc/crypto/RSA_generate_key.pod +++ b/doc/crypto/RSA_generate_key.pod @@ -19,7 +19,7 @@ be seeded prior to calling RSA_generate_key(). The modulus size will be B bits, and the public exponent will be B. Key sizes with B E 1024 should be considered insecure. -The exponent is an odd number, typically 3 or 65535. +The exponent is an odd number, typically 3, 17 or 65537. A callback function may be used to provide feedback about the progress of the key generation. If B is not B, it diff --git a/shlib/Makefile.hpux10-cc b/shlib/Makefile.hpux10-cc index 4dc62ebd9e..ecc6ad637d 100644 --- a/shlib/Makefile.hpux10-cc +++ b/shlib/Makefile.hpux10-cc @@ -1,12 +1,12 @@ # Makefile.hpux-cc -major=1 +major=0.9.6d slib=libssl -sh_slib=$(slib).so.$(major) +sh_slib=$(slib).sl.$(major) clib=libcrypto -sh_clib=$(clib).so.$(major) +sh_clib=$(clib).sl.$(major) all : $(clib).sl $(slib).sl @@ -20,31 +20,14 @@ $(slib)_pic.a : $(slib).a cp -p $? $@ $(sh_clib) : $(clib)_pic.a - echo "collecting all object files for $@" - find . -name \*.o -print > allobjs - for obj in `ar t $(clib)_pic.a`; \ - do \ - grep /$$obj allobjs; \ - done >objlist - echo "linking $@" - ld -b -s -z +h $@ -o $@ `cat objlist` -lc - rm allobjs objlist + ld -b -s -z +h $@ -o $@ -Fl $(clib)_pic.a -ldld -lc $(clib).sl : $(sh_clib) rm -f $@ ln -s $? $@ $(sh_slib) : $(slib)_pic.a $(clib).sl - echo "collecting all object files for $@" - find . -name \*.o -print > allobjs - for obj in `ar t $(slib)_pic.a`; \ - do \ - grep /$$obj allobjs; \ - done >objlist - echo "linking $@" - ld -b -s -z +h $@ +b /usr/local/ssl/lib:/usr/lib -o $@ `cat objlist` \ - -L. -lcrypto -lc - rm -f allobjs objlist + ld -b -s -z +h $@ -o $@ -Fl $(slib)_pic.a -ldld -lc $(slib).sl : $(sh_slib) rm -f $@ diff --git a/shlib/hpux10-cc.sh b/shlib/hpux10-cc.sh index 903baaa4e7..5a9be6dbff 100644 --- a/shlib/hpux10-cc.sh +++ b/shlib/hpux10-cc.sh @@ -20,7 +20,9 @@ # WARNING: At high optimization levels, HP's ANSI-C compiler can chew up # large amounts of memory and CPU time. Make sure to have at least # 128MB of RAM available and that your kernel is configured to allow -# at least 128MB data size (maxdsiz parameter). +# at least 128MB data size (maxdsiz parameter which can be obtained +# by multiplying 'echo maxdsiz/D | adb -k /stand/vmunix /dev/kmem' +# by 'getconf PAGE_SIZE'). # The installation process can take several hours, even on fast # machines. +O4 optimization of the libcrypto.sl shared library may # take 1 hour on a C200 (200MHz PA8200 CPU), +O3 compilation of @@ -40,7 +42,7 @@ SITEFLAGS="+DAportable +w1" MYFLAGS="-D_REENTRANT +Oall $SITEFLAGS" # Configure for pic and build the static pic libraries -perl5 Configure hpux-parisc-cc-o4 +z ${MYFLAGS} +perl5 Configure no-shared hpux-parisc-cc-o4 +Z ${MYFLAGS} make clean make DIRS="crypto ssl" # Rename the static pic libs and build dynamic libraries from them @@ -58,21 +60,21 @@ mkdir /usr/local mkdir /usr/local/ssl mkdir /usr/local/ssl/lib chmod 444 lib*_pic.a -chmod 555 lib*.so.1 -cp -p lib*_pic.a lib*.so.1 /usr/local/ssl/lib -(cd /usr/local/ssl/lib ; ln -sf libcrypto.so.1 libcrypto.sl ; ln -sf libssl.so.1 libssl.sl) +chmod 555 lib*.sl.0.9.6d +cp -p lib*_pic.a lib*.sl.0.9.6d /usr/local/ssl/lib +(cd /usr/local/ssl/lib ; ln -sf libcrypto.sl.0.9.6d libcrypto.sl ; ln -sf libssl.sl.0.9.6d libssl.sl) # Reconfigure without pic to compile the executables. Unfortunately, while # performing this task we have to recompile the library components, even # though we use the already installed shared libs anyway. # -perl5 Configure hpux-parisc-cc-o4 ${MYFLAGS} +perl5 Configure no-shared hpux-parisc-cc-o4 ${MYFLAGS} make clean # Hack the Makefiles to pick up the dynamic libraries during linking # -sed 's/^PEX_LIBS=.*$/PEX_LIBS=-L\/usr\/local\/ssl\/lib -Wl,+b,\/usr\/local\/ssl\/lib:\/usr\/lib/' Makefile.ssl >xxx; mv xxx Makefile.ssl +sed 's/^PEX_LIBS=.*$/PEX_LIBS=-L\/usr\/local\/ssl\/lib/' Makefile.ssl >xxx; mv xxx Makefile.ssl sed 's/-L\.\.//' apps/Makefile.ssl >xxx; mv xxx apps/Makefile.ssl sed 's/-L\.\.//' test/Makefile.ssl >xxx; mv xxx test/Makefile.ssl # Build the static libs and the executables in one make. @@ -83,7 +85,7 @@ make install # Finally build the static libs with +O3. This time we only need the libraries, # once created, they are simply copied into place. # -perl5 Configure hpux-parisc-cc ${MYFLAGS} +perl5 Configure no-shared hpux-parisc-cc ${MYFLAGS} make clean make DIRS="crypto ssl" chmod 644 libcrypto.a libssl.a diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 49b159d290..beb562868d 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2002 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 @@ -572,6 +572,7 @@ int ssl3_setup_buffers(SSL *s) { unsigned char *p; unsigned int extra; + size_t len; if (s->s3->rbuf.buf == NULL) { @@ -579,18 +580,21 @@ int ssl3_setup_buffers(SSL *s) extra=SSL3_RT_MAX_EXTRA; else extra=0; - if ((p=OPENSSL_malloc(SSL3_RT_MAX_PACKET_SIZE+extra)) - == NULL) + len = SSL3_RT_MAX_PACKET_SIZE + extra; + if ((p=OPENSSL_malloc(len)) == NULL) goto err; - s->s3->rbuf.buf=p; + s->s3->rbuf.buf = p; + s->s3->rbuf_len = len; } if (s->s3->wbuf.buf == NULL) { - if ((p=OPENSSL_malloc(SSL3_RT_MAX_PACKET_SIZE)) - == NULL) + len = SSL3_RT_MAX_PACKET_SIZE; + len += SSL3_RT_HEADER_LENGTH + 256; /* extra space for empty fragment */ + if ((p=OPENSSL_malloc(len)) == NULL) goto err; - s->s3->wbuf.buf=p; + s->s3->wbuf.buf = p; + s->s3->wbuf_len = len; } s->packet= &(s->s3->rbuf.buf[0]); return(1); diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index af7075e920..d9a161ad8b 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2002 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ #include #include @@ -305,9 +358,17 @@ int ssl3_setup_key_block(SSL *s) s->s3->tmp.key_block_length=num; s->s3->tmp.key_block=p; - + ssl3_generate_key_block(s,p,num); - + + /* enable vulnerability countermeasure for CBC ciphers with + * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) */ + s->s3->need_empty_fragments = 1; +#ifndef NO_RC4 + if ((s->session->cipher != NULL) && ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)) + s->s3->need_empty_fragments = 0; +#endif + return(1); err: SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 597343232f..57a3fa4f81 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -740,6 +740,7 @@ void ssl3_free(SSL *s) void ssl3_clear(SSL *s) { unsigned char *rp,*wp; + size_t rlen, wlen; ssl3_cleanup_key_block(s); if (s->s3->tmp.ca_names != NULL) @@ -755,12 +756,16 @@ void ssl3_clear(SSL *s) DH_free(s->s3->tmp.dh); #endif - rp=s->s3->rbuf.buf; - wp=s->s3->wbuf.buf; + rp = s->s3->rbuf.buf; + wp = s->s3->wbuf.buf; + rlen = s->s3->rbuf_len; + wlen = s->s3->wbuf_len; memset(s->s3,0,sizeof *s->s3); - if (rp != NULL) s->s3->rbuf.buf=rp; - if (wp != NULL) s->s3->wbuf.buf=wp; + s->s3->rbuf.buf = rp; + s->s3->wbuf.buf = wp; + s->s3->rbuf_len = rlen; + s->s3->wbuf_len = wlen; ssl_free_wbio_buffer(s); @@ -1315,13 +1320,12 @@ static int ssl3_read_internal(SSL *s, void *buf, int len, int peek) if (s->s3->renegotiate) ssl3_renegotiate_check(s); s->s3->in_read_app_data=1; ret=ssl3_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek); - if ((ret == -1) && (s->s3->in_read_app_data == 0)) + if ((ret == -1) && (s->s3->in_read_app_data == 2)) { /* ssl3_read_bytes decided to call s->handshake_func, which * called ssl3_read_bytes to read handshake data. * However, ssl3_read_bytes actually found application data - * and thinks that application data makes sense here (signalled - * by resetting 'in_read_app_data', strangely); so disable + * and thinks that application data makes sense here; so disable * handshake processing and try to read application data again. */ s->in_handshake++; ret=ssl3_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek); diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index 5f1f7ad303..fb086dcc86 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2002 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 @@ -117,7 +117,7 @@ #include "ssl_locl.h" static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - unsigned int len); + unsigned int len, int create_empty_fragment); static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len); static int ssl3_get_record(SSL *s); @@ -162,9 +162,7 @@ static int ssl3_read_n(SSL *s, int n, int max, int extend) { /* avoid buffer overflow */ - int max_max = SSL3_RT_MAX_PACKET_SIZE - s->packet_length; - if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) - max_max += SSL3_RT_MAX_EXTRA; + int max_max = s->s3->rbuf_len - s->packet_length; if (max > max_max) max = max_max; } @@ -247,14 +245,20 @@ static int ssl3_get_record(SSL *s) extra=SSL3_RT_MAX_EXTRA; else extra=0; + if (extra != (s->s3->rbuf_len - SSL3_RT_MAX_PACKET_SIZE)) + { + /* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER + * set after ssl3_setup_buffers() was done */ + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_INTERNAL_ERROR); + return -1; + } again: /* check if we have the header */ if ( (s->rstate != SSL_ST_READ_BODY) || (s->packet_length < SSL3_RT_HEADER_LENGTH)) { - n=ssl3_read_n(s,SSL3_RT_HEADER_LENGTH, - SSL3_RT_MAX_PACKET_SIZE,0); + n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf_len, 0); if (n <= 0) return(n); /* error or non-blocking */ s->rstate=SSL_ST_READ_BODY; @@ -509,7 +513,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) if (i == 0) { SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); - return(-1); + return -1; } } @@ -521,18 +525,22 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) else nw=n; - i=do_ssl3_write(s,type,&(buf[tot]),nw); + i=do_ssl3_write(s, type, &(buf[tot]), nw, 0); if (i <= 0) { s->s3->wnum=tot; - return(i); + return i; } if ((i == (int)n) || (type == SSL3_RT_APPLICATION_DATA && (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { - return(tot+i); + /* next chunk of data should get another prepended empty fragment + * in ciphersuites with known-IV weakness: */ + s->s3->empty_fragment_done = 0; + + return tot+i; } n-=i; @@ -541,15 +549,16 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) } static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - unsigned int len) + unsigned int len, int create_empty_fragment) { unsigned char *p,*plen; int i,mac_size,clear=0; + int prefix_len = 0; SSL3_RECORD *wr; SSL3_BUFFER *wb; SSL_SESSION *sess; - /* first check is there is a SSL3_RECORD still being written + /* first check if there is a SSL3_BUFFER still being written * out. This will happen with non blocking IO */ if (s->s3->wbuf.left != 0) return(ssl3_write_pending(s,type,buf,len)); @@ -563,7 +572,8 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* if it went, fall through and send more stuff */ } - if (len == 0) return(len); + if (len == 0 && !create_empty_fragment) + return 0; wr= &(s->s3->wrec); wb= &(s->s3->wbuf); @@ -579,16 +589,44 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, else mac_size=EVP_MD_size(s->write_hash); - p=wb->buf; + /* 'create_empty_fragment' is true only when this function calls itself */ + if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) + { + /* countermeasure against known-IV weakness in CBC ciphersuites + * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ + + if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) + { + /* recursive function call with 'create_empty_fragment' set; + * this prepares and buffers the data for an empty fragment + * (these 'prefix_len' bytes are sent out later + * together with the actual payload) */ + prefix_len = do_ssl3_write(s, type, buf, 0, 1); + if (prefix_len <= 0) + goto err; + + if (s->s3->wbuf_len < prefix_len + SSL3_RT_MAX_PACKET_SIZE) + { + /* insufficient space */ + SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_INTERNAL_ERROR); + goto err; + } + } + + s->s3->empty_fragment_done = 1; + } + + p = wb->buf + prefix_len; /* write the header */ + *(p++)=type&0xff; wr->type=type; *(p++)=(s->version>>8); *(p++)=s->version&0xff; - /* record where we are to write out packet length */ + /* field where we are to write out packet length */ plen=p; p+=2; @@ -639,19 +677,28 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, wr->type=type; /* not needed but helps for debugging */ wr->length+=SSL3_RT_HEADER_LENGTH; - /* Now lets setup wb */ - wb->left=wr->length; - wb->offset=0; + if (create_empty_fragment) + { + /* we are in a recursive call; + * just return the length, don't write out anything here + */ + return wr->length; + } + /* now let's set up wb */ + wb->left = prefix_len + wr->length; + wb->offset = 0; + + /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ s->s3->wpend_tot=len; s->s3->wpend_buf=buf; s->s3->wpend_type=type; s->s3->wpend_ret=len; /* we now just need to write the buffer */ - return(ssl3_write_pending(s,type,buf,len)); + return ssl3_write_pending(s,type,buf,len); err: - return(-1); + return -1; } /* if s->s3->wbuf.left != 0, we need to call this */ @@ -1114,7 +1161,7 @@ start: ) )) { - s->s3->in_read_app_data=0; + s->s3->in_read_app_data=2; return(-1); } else @@ -1200,7 +1247,7 @@ int ssl3_dispatch_alert(SSL *s) void (*cb)()=NULL; s->s3->alert_dispatch=0; - i=do_ssl3_write(s,SSL3_RT_ALERT,&s->s3->send_alert[0],2); + i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0); if (i <= 0) { s->s3->alert_dispatch=1; diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 605581e816..2319737fed 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -711,7 +711,7 @@ static int ssl3_get_client_hello(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_SPECIFIED); goto f_err; } - if ((i+p) > (d+n)) + if ((p+i) >= (d+n)) { /* not enough data */ al=SSL_AD_DECODE_ERROR; @@ -768,6 +768,13 @@ static int ssl3_get_client_hello(SSL *s) /* compression */ i= *(p++); + if ((p+i) > (d+n)) + { + /* not enough data */ + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH); + goto f_err; + } q=p; for (j=0; jversion == SSL3_VERSION) { - if (p > (d+n)) + if (p < (d+n)) { /* wrong number of bytes, * there could be more to follow */ diff --git a/ssl/ssl3.h b/ssl/ssl3.h index 7ee1feaa67..b45effe052 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2002 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ #ifndef HEADER_SSL3_H #define HEADER_SSL3_H @@ -201,10 +254,13 @@ typedef struct ssl3_record_st typedef struct ssl3_buffer_st { - unsigned char *buf; /* SSL3_RT_MAX_PACKET_SIZE bytes (more if - * SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER is set) */ - int offset; /* where to 'copy from' */ - int left; /* how many bytes left */ + unsigned char *buf; /* at least SSL3_RT_MAX_PACKET_SIZE bytes, + * see ssl3_setup_buffers() */ +#if 0 /* put directly into SSL3_STATE for best possible binary compatibility within 0.9.6 series */ + size_t len; /* buffer size */ +#endif + int offset; /* where to 'copy from' */ + int left; /* how many bytes left */ } SSL3_BUFFER; #define SSL3_CT_RSA_SIGN 1 @@ -321,6 +377,13 @@ typedef struct ssl3_state_st int cert_request; } tmp; + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + + size_t rbuf_len; /* substitute for rbuf.len */ + size_t wbuf_len; /* substitute for wbuf.len */ + } SSL3_STATE; /* SSLv3 */ diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index ff4f0c8ca9..b752e891c3 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2002 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ #include #include @@ -380,6 +433,14 @@ printf("\nkey block\n"); { int z; for (z=0; zs3->need_empty_fragments = 1; +#ifndef NO_RC4 + if ((s->session->cipher != NULL) && ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)) + s->s3->need_empty_fragments = 0; +#endif + return(1); err: SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); -- 2.25.1