Implement known-IV countermeasure.

Fix length checks in ssl3_get_client_hello().

Use s->s3->in_read_app_data differently to fix ssl3_read_internal().
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 89b54b7..58a24cd 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 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
@@ -592,6 +592,7 @@
 	{
 	unsigned char *p;
 	unsigned int extra;
+	size_t len;
 
 	if (s->s3->rbuf.buf == NULL)
 		{
@@ -599,18 +600,21 @@
 			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 6d9f986..6dfef5c 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 <stdio.h>
 #include <openssl/evp.h>
@@ -296,6 +349,7 @@
 	const EVP_CIPHER *c;
 	const EVP_MD *hash;
 	int num;
+	int ret = 0;
 	SSL_COMP *comp;
 
 	if (s->s3->tmp.key_block_length != 0)
@@ -322,8 +376,18 @@
 	s->s3->tmp.key_block_length=num;
 	s->s3->tmp.key_block=p;
 
-	return ssl3_generate_key_block(s,p,num);
+	ret = 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 OPENSSL_NO_RC4
+	if ((s->session->cipher != NULL) && ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4))
+		s->s3->need_empty_fragments = 0;
+#endif
+
+	return ret;
+		
 err:
 	SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
 	return(0);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 4ccc70b..6869924 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -994,6 +994,7 @@
 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)
@@ -1009,15 +1010,19 @@
 		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;
 
 	EVP_MD_CTX_cleanup(&s->s3->finish_dgst1);
 	EVP_MD_CTX_cleanup(&s->s3->finish_dgst2);
 
 	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);
 
@@ -1609,13 +1614,12 @@
 	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 616698f..5e60e18 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 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 @@
 
 	{
 		/* 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 @@
 		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, ERR_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 @@
 		if (i == 0)
 			{
 			SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
-			return(-1);
+			return -1;
 			}
 		}
 
@@ -521,18 +525,22 @@
 		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 @@
 	}
 
 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 @@
 		/* 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 @@
 	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, ERR_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 @@
 	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 */
@@ -1124,7 +1171,7 @@
 					)
 				))
 			{
-			s->s3->in_read_app_data=0;
+			s->s3->in_read_app_data=2;
 			return(-1);
 			}
 		else
@@ -1210,7 +1257,7 @@
 	void (*cb)(const SSL *ssl,int type,int val)=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 d6247a6..99b6a86 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -727,7 +727,7 @@
 		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;
@@ -784,6 +784,13 @@
 
 	/* 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; j<i; j++)
 		{
@@ -831,7 +838,7 @@
 	/* TLS does not mind if there is extra stuff */
 	if (s->version == 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 0528588..8fd6951 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 
@@ -218,10 +271,11 @@
 
 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() */
+	size_t len;             /* buffer size */
+	int offset;             /* where to 'copy from' */
+	int left;               /* how many bytes left */
 	} SSL3_BUFFER;
 
 #define SSL3_CT_RSA_SIGN			1
@@ -251,6 +305,10 @@
 	unsigned char server_random[SSL3_RANDOM_SIZE];
 	unsigned char client_random[SSL3_RANDOM_SIZE];
 
+	/* flags for countermeasure against known-IV weakness */
+	int need_empty_fragments;
+	int empty_fragment_done;
+
 	SSL3_BUFFER rbuf;	/* read IO goes into here */
 	SSL3_BUFFER wbuf;	/* write IO goes into here */
 
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 8b7844c..b80525f 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 <stdio.h>
 #include <openssl/comp.h>
@@ -430,6 +483,14 @@
 { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
 #endif
 
+	/* 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_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);