Blob Blame History Raw
diff -up openssl-1.0.0-beta4/apps/s_cb.c.reneg openssl-1.0.0-beta4/apps/s_cb.c
--- openssl-1.0.0-beta4/apps/s_cb.c.reneg	2009-10-15 20:48:47.000000000 +0200
+++ openssl-1.0.0-beta4/apps/s_cb.c	2009-11-12 15:02:30.000000000 +0100
@@ -669,6 +669,10 @@ void MS_CALLBACK tlsext_cb(SSL *s, int c
 		extname = "server ticket";
 		break;
 
+		case TLSEXT_TYPE_renegotiate:
+		extname = "renegotiate";
+		break;
+
 #ifdef TLSEXT_TYPE_opaque_prf_input
 		case TLSEXT_TYPE_opaque_prf_input:
 		extname = "opaque PRF input";
diff -up openssl-1.0.0-beta4/apps/s_client.c.reneg openssl-1.0.0-beta4/apps/s_client.c
--- openssl-1.0.0-beta4/apps/s_client.c.reneg	2009-11-12 14:57:48.000000000 +0100
+++ openssl-1.0.0-beta4/apps/s_client.c	2009-11-12 15:01:48.000000000 +0100
@@ -343,6 +343,7 @@ static void sc_usage(void)
 	BIO_printf(bio_err," -status           - request certificate status from server\n");
 	BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
 #endif
+	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
 	}
 
 #ifndef OPENSSL_NO_TLSEXT
@@ -657,6 +658,8 @@ int MAIN(int argc, char **argv)
 #endif
 		else if (strcmp(*argv,"-serverpref") == 0)
 			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
+		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
 		else if	(strcmp(*argv,"-cipher") == 0)
 			{
 			if (--argc < 1) goto bad;
diff -up openssl-1.0.0-beta4/apps/s_server.c.reneg openssl-1.0.0-beta4/apps/s_server.c
--- openssl-1.0.0-beta4/apps/s_server.c.reneg	2009-11-12 14:57:48.000000000 +0100
+++ openssl-1.0.0-beta4/apps/s_server.c	2009-11-12 15:01:48.000000000 +0100
@@ -491,6 +491,7 @@ static void sv_usage(void)
 	BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT2);
 	BIO_printf(bio_err," -tlsextdebug  - hex dump of all TLS extensions received\n");
 	BIO_printf(bio_err," -no_ticket    - disable use of RFC4507bis session tickets\n");
+	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
 #endif
 	}
 
@@ -1013,6 +1014,8 @@ int MAIN(int argc, char *argv[])
 			verify_return_error = 1;
 		else if	(strcmp(*argv,"-serverpref") == 0)
 			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
+		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
 		else if	(strcmp(*argv,"-cipher") == 0)
 			{
 			if (--argc < 1) goto bad;
diff -up openssl-1.0.0-beta4/ssl/tls1.h.reneg openssl-1.0.0-beta4/ssl/tls1.h
--- openssl-1.0.0-beta4/ssl/tls1.h.reneg	2009-11-12 14:57:47.000000000 +0100
+++ openssl-1.0.0-beta4/ssl/tls1.h	2009-11-12 15:02:30.000000000 +0100
@@ -201,6 +201,9 @@ extern "C" {
 # define TLSEXT_TYPE_opaque_prf_input		?? */
 #endif
 
+/* Temporary extension type */
+#define TLSEXT_TYPE_renegotiate                 0xff01
+
 /* NameType value from RFC 3546 */
 #define TLSEXT_NAMETYPE_host_name 0
 /* status request value from RFC 3546 */
diff -up openssl-1.0.0-beta4/ssl/t1_lib.c.reneg openssl-1.0.0-beta4/ssl/t1_lib.c
--- openssl-1.0.0-beta4/ssl/t1_lib.c.reneg	2009-11-08 15:36:32.000000000 +0100
+++ openssl-1.0.0-beta4/ssl/t1_lib.c	2009-11-12 15:02:30.000000000 +0100
@@ -315,6 +315,30 @@ unsigned char *ssl_add_clienthello_tlsex
 		ret+=size_str;
 		}
 
+        /* Add the renegotiation option: TODOEKR switch */
+        {
+          int el;
+          
+          if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
+              {
+              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          if((limit - p - 4 - el) < 0) return NULL;
+          
+          s2n(TLSEXT_TYPE_renegotiate,ret);
+          s2n(el,ret);
+
+          if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
+              {
+              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          ret += el;
+        }
+
 #ifndef OPENSSL_NO_EC
 	if (s->tlsext_ecpointformatlist != NULL)
 		{
@@ -490,6 +514,31 @@ unsigned char *ssl_add_serverhello_tlsex
 		s2n(TLSEXT_TYPE_server_name,ret);
 		s2n(0,ret);
 		}
+
+        if(s->s3->send_connection_binding)
+        {
+          int el;
+          
+          if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
+              {
+              SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          if((limit - p - 4 - el) < 0) return NULL;
+          
+          s2n(TLSEXT_TYPE_renegotiate,ret);
+          s2n(el,ret);
+
+          if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
+              {
+              SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          ret += el;
+        }
+
 #ifndef OPENSSL_NO_EC
 	if (s->tlsext_ecpointformatlist != NULL)
 		{
@@ -574,11 +623,23 @@ int ssl_parse_clienthello_tlsext(SSL *s,
 	unsigned short size;
 	unsigned short len;
 	unsigned char *data = *p;
+	int renegotiate_seen = 0;
+
 	s->servername_done = 0;
 	s->tlsext_status_type = -1;
+	s->s3->send_connection_binding = 0;
 
 	if (data >= (d+n-2))
+		{
+		if (s->new_session
+			&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+			{
+			/* We should always see one extension: the renegotiate extension */
+			*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
+			return 0;
+			}
 		return 1;
+		}
 	n2s(data,len);
 
 	if (data > (d+n-len)) 
@@ -790,6 +851,12 @@ int ssl_parse_clienthello_tlsext(SSL *s,
 				return 0;
 				}
 			}
+		else if (type == TLSEXT_TYPE_renegotiate)
+			{
+			if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
+				return 0;
+			renegotiate_seen = 1;
+			}
 		else if (type == TLSEXT_TYPE_status_request
 						&& s->ctx->tlsext_status_cb)
 			{
@@ -894,6 +961,14 @@ int ssl_parse_clienthello_tlsext(SSL *s,
 		/* session ticket processed earlier */
 		data+=size;
 		}
+  
+ 	if (s->new_session && !renegotiate_seen
+ 		&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+ 		{
+ 		*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
+ 		return 0;
+ 		}
+ 
 				
 	*p = data;
 	return 1;
@@ -905,11 +980,22 @@ int ssl_parse_serverhello_tlsext(SSL *s,
 	unsigned short size;
 	unsigned short len;  
 	unsigned char *data = *p;
-
 	int tlsext_servername = 0;
+	int renegotiate_seen = 0;
 
 	if (data >= (d+n-2))
+		{
+		/* Because the client does not see any renegotiation during an
+		   attack, we must enforce this on all server hellos, even the
+		   first */
+		if (!(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+			{
+			/* We should always see one extension: the renegotiate extension */
+			*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
+			return 0;
+			}
 		return 1;
+		}
 
 	n2s(data,len);
 
@@ -1025,7 +1111,12 @@ int ssl_parse_serverhello_tlsext(SSL *s,
 			/* Set flag to expect CertificateStatus message */
 			s->tlsext_status_expected = 1;
 			}
-
+		else if (type == TLSEXT_TYPE_renegotiate)
+			{
+			if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+				return 0;
+			renegotiate_seen = 1;
+			}
 		data+=size;		
 		}
 
@@ -1035,6 +1126,13 @@ int ssl_parse_serverhello_tlsext(SSL *s,
 		return 0;
 		}
 
+	if (!renegotiate_seen
+		&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+		{
+		*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
+		return 0;
+		}
+
 	if (!s->hit && tlsext_servername == 1)
 		{
  		if (s->tlsext_hostname)