Blame SOURCES/openssl-fips-0.9.8e-cve-2009-3555.patch

c4366c
diff -up openssl-fips-0.9.8e/apps/s_client.c.reneg openssl-fips-0.9.8e/apps/s_client.c
c4366c
--- openssl-fips-0.9.8e/apps/s_client.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/apps/s_client.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -231,7 +231,7 @@ static void sc_usage(void)
c4366c
 	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
c4366c
 #endif
c4366c
 	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
c4366c
-
c4366c
+	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
c4366c
 	}
c4366c
 
c4366c
 enum
c4366c
@@ -247,7 +247,7 @@ int MAIN(int, char **);
c4366c
 
c4366c
 int MAIN(int argc, char **argv)
c4366c
 	{
c4366c
-	int off=0;
c4366c
+	int off=0, clr = 0;
c4366c
 	SSL *con=NULL,*con2=NULL;
c4366c
 	X509_STORE *store = NULL;
c4366c
 	int s,k,width,state=0;
c4366c
@@ -461,6 +461,12 @@ int MAIN(int argc, char **argv)
c4366c
 			off|=SSL_OP_NO_SSLv2;
c4366c
 		else if (strcmp(*argv,"-serverpref") == 0)
c4366c
 			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
c4366c
+		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
c4366c
+			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
c4366c
+		else if	(strcmp(*argv,"-legacy_server_connect") == 0)
c4366c
+			{ off|=SSL_OP_LEGACY_SERVER_CONNECT; }
c4366c
+		else if	(strcmp(*argv,"-no_legacy_server_connect") == 0)
c4366c
+			{ clr|=SSL_OP_LEGACY_SERVER_CONNECT; }
c4366c
 		else if	(strcmp(*argv,"-cipher") == 0)
c4366c
 			{
c4366c
 			if (--argc < 1) goto bad;
c4366c
@@ -589,6 +595,9 @@ bad:
c4366c
 		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
c4366c
 	else
c4366c
 		SSL_CTX_set_options(ctx,off);
c4366c
+
c4366c
+	if (clr)
c4366c
+		SSL_CTX_clear_options(ctx, clr);
c4366c
 	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
c4366c
 	 * Setting read ahead solves this problem.
c4366c
 	 */
c4366c
@@ -1290,6 +1299,8 @@ static void print_stuff(BIO *bio, SSL *s
c4366c
 							 EVP_PKEY_bits(pktmp));
c4366c
 		EVP_PKEY_free(pktmp);
c4366c
 	}
c4366c
+	BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
c4366c
+			SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
c4366c
 #ifndef OPENSSL_NO_COMP
c4366c
 	comp=SSL_get_current_compression(s);
c4366c
 	expansion=SSL_get_current_expansion(s);
c4366c
diff -up openssl-fips-0.9.8e/apps/s_server.c.reneg openssl-fips-0.9.8e/apps/s_server.c
c4366c
--- openssl-fips-0.9.8e/apps/s_server.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/apps/s_server.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -371,6 +371,7 @@ static void sv_usage(void)
c4366c
 #endif
c4366c
 	BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
c4366c
 	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
c4366c
+	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
c4366c
 	}
c4366c
 
c4366c
 static int local_argc=0;
c4366c
@@ -700,6 +701,8 @@ int MAIN(int argc, char *argv[])
c4366c
 			}
c4366c
 		else if	(strcmp(*argv,"-serverpref") == 0)
c4366c
 			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
c4366c
+		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
c4366c
+			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
c4366c
 		else if	(strcmp(*argv,"-cipher") == 0)
c4366c
 			{
c4366c
 			if (--argc < 1) goto bad;
c4366c
@@ -1534,6 +1537,8 @@ static int init_ssl_connection(SSL *con)
c4366c
 			con->kssl_ctx->client_princ);
c4366c
 		}
c4366c
 #endif /* OPENSSL_NO_KRB5 */
c4366c
+	BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
c4366c
+		      SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
c4366c
 	return(1);
c4366c
 	}
c4366c
 
c4366c
diff -up openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod.reneg openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod
c4366c
--- openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod.reneg	2005-10-11 12:16:09.000000000 +0200
c4366c
+++ openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod	2010-02-18 16:10:52.000000000 +0100
c4366c
@@ -2,7 +2,7 @@
c4366c
 
c4366c
 =head1 NAME
c4366c
 
c4366c
-SSL_CTX_set_options, SSL_set_options, SSL_CTX_get_options, SSL_get_options - manipulate SSL engine options
c4366c
+SSL_CTX_set_options, SSL_set_options, SSL_CTX_clear_options, SSL_clear_options, SSL_CTX_get_options, SSL_get_options, SSL_get_secure_renegotiation_support - manipulate SSL options
c4366c
 
c4366c
 =head1 SYNOPSIS
c4366c
 
c4366c
@@ -11,26 +11,41 @@ SSL_CTX_set_options, SSL_set_options, SS
c4366c
  long SSL_CTX_set_options(SSL_CTX *ctx, long options);
c4366c
  long SSL_set_options(SSL *ssl, long options);
c4366c
 
c4366c
+ long SSL_CTX_clear_options(SSL_CTX *ctx, long options);
c4366c
+ long SSL_clear_options(SSL *ssl, long options);
c4366c
+
c4366c
  long SSL_CTX_get_options(SSL_CTX *ctx);
c4366c
  long SSL_get_options(SSL *ssl);
c4366c
 
c4366c
+ long SSL_get_secure_renegotiation_support(SSL *ssl);
c4366c
+
c4366c
 =head1 DESCRIPTION
c4366c
 
c4366c
+Note: all these functions are implemented using macros.
c4366c
+
c4366c
 SSL_CTX_set_options() adds the options set via bitmask in B<options> to B<ctx>.
c4366c
 Options already set before are not cleared!
c4366c
 
c4366c
 SSL_set_options() adds the options set via bitmask in B<options> to B<ssl>.
c4366c
 Options already set before are not cleared!
c4366c
 
c4366c
+SSL_CTX_clear_options() clears the options set via bitmask in B<options>
c4366c
+to B<ctx>.
c4366c
+
c4366c
+SSL_clear_options() clears the options set via bitmask in B<options> to B<ssl>.
c4366c
+
c4366c
 SSL_CTX_get_options() returns the options set for B<ctx>.
c4366c
 
c4366c
 SSL_get_options() returns the options set for B<ssl>.
c4366c
 
c4366c
+SSL_get_secure_renegotiation_support() indicates whether the peer supports
c4366c
+secure renegotiation.
c4366c
+
c4366c
 =head1 NOTES
c4366c
 
c4366c
 The behaviour of the SSL library can be changed by setting several options.
c4366c
 The options are coded as bitmasks and can be combined by a logical B<or>
c4366c
-operation (|). Options can only be added but can never be reset.
c4366c
+operation (|).
c4366c
 
c4366c
 SSL_CTX_set_options() and SSL_set_options() affect the (external)
c4366c
 protocol behaviour of the SSL library. The (internal) behaviour of
c4366c
@@ -199,17 +214,109 @@ Do not use the TLSv1 protocol.
c4366c
 
c4366c
 When performing renegotiation as a server, always start a new session
c4366c
 (i.e., session resumption requests are only accepted in the initial
c4366c
-handshake).  This option is not needed for clients.
c4366c
+handshake). This option is not needed for clients.
c4366c
+
c4366c
+=item SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
c4366c
+
c4366c
+Allow legacy insecure renegotiation between OpenSSL and unpatched clients or
c4366c
+servers. See the B<SECURE RENEGOTIATION> section for more details.
c4366c
+
c4366c
+=item SSL_OP_LEGACY_SERVER_CONNECT
c4366c
+
c4366c
+Allow legacy insecure renegotiation between OpenSSL and unpatched servers
c4366c
+B<only>: this option is currently set by default. See the
c4366c
+B<SECURE RENEGOTIATION> section for more details.
c4366c
 
c4366c
 =back
c4366c
 
c4366c
+=head1 SECURE RENEGOTIATION
c4366c
+
c4366c
+OpenSSL 0.9.8m and later always attempts to use secure renegotiation as
c4366c
+described in RFC5746. This counters the prefix attack described in
c4366c
+CVE-2009-3555 and elsewhere.
c4366c
+
c4366c
+The deprecated and highly broken SSLv2 protocol does not support
c4366c
+renegotiation at all: its use is B<strongly> discouraged.
c4366c
+
c4366c
+This attack has far reaching consequences which application writers should be
c4366c
+aware of. In the description below an implementation supporting secure
c4366c
+renegotiation is referred to as I<patched>. A server not supporting secure
c4366c
+renegotiation is referred to as I<unpatched>.
c4366c
+
c4366c
+The following sections describe the operations permitted by OpenSSL's secure
c4366c
+renegotiation implementation.
c4366c
+
c4366c
+=head2 Patched client and server
c4366c
+
c4366c
+Connections and renegotiation are always permitted by OpenSSL implementations.
c4366c
+
c4366c
+=head2 Unpatched client and patched OpenSSL server
c4366c
+
c4366c
+The initial connection suceeds but client renegotiation is denied by the
c4366c
+server with a B<no_renegotiation> warning alert if TLS v1.0 is used or a fatal
c4366c
+B<handshake_failure> alert in SSL v3.0.
c4366c
+
c4366c
+If the patched OpenSSL server attempts to renegotiate a fatal
c4366c
+B<handshake_failure> alert is sent. This is because the server code may be
c4366c
+unaware of the unpatched nature of the client.
c4366c
+
c4366c
+If the option B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> is set then
c4366c
+renegotiation B<always> succeeds.
c4366c
+
c4366c
+B<NB:> a bug in OpenSSL clients earlier than 0.9.8m (all of which are
c4366c
+unpatched) will result in the connection hanging if it receives a
c4366c
+B<no_renegotiation> alert. OpenSSL versions 0.9.8m and later will regard
c4366c
+a B<no_renegotiation> alert as fatal and respond with a fatal
c4366c
+B<handshake_failure> alert. This is because the OpenSSL API currently has
c4366c
+no provision to indicate to an application that a renegotiation attempt
c4366c
+was refused.
c4366c
+
c4366c
+=head2 Patched OpenSSL client and unpatched server.
c4366c
+
c4366c
+If the option B<SSL_OP_LEGACY_SERVER_CONNECT> or
c4366c
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> is set then initial connections
c4366c
+and renegotiation between patched OpenSSL clients and unpatched servers
c4366c
+succeeds. If neither option is set then initial connections to unpatched
c4366c
+servers will fail.
c4366c
+
c4366c
+The option B<SSL_OP_LEGACY_SERVER_CONNECT> is currently set by default even
c4366c
+though it has security implications: otherwise it would be impossible to
c4366c
+connect to unpatched servers (i.e. all of them initially) and this is clearly
c4366c
+not acceptable. Renegotiation is permitted because this does not add any
c4366c
+additional security issues: during an attack clients do not see any
c4366c
+renegotiations anyway.
c4366c
+
c4366c
+As more servers become patched the option B<SSL_OP_LEGACY_SERVER_CONNECT> will
c4366c
+B<not> be set by default in a future version of OpenSSL.
c4366c
+
c4366c
+OpenSSL client applications wishing to ensure they can connect to unpatched
c4366c
+servers should always B<set> B<SSL_OP_LEGACY_SERVER_CONNECT>
c4366c
+
c4366c
+OpenSSL client applications that want to ensure they can B<not> connect to
c4366c
+unpatched servers (and thus avoid any security issues) should always B<clear>
c4366c
+B<SSL_OP_LEGACY_SERVER_CONNECT> using SSL_CTX_clear_options() or
c4366c
+SSL_clear_options().
c4366c
+
c4366c
+The difference between the B<SSL_OP_LEGACY_SERVER_CONNECT> and
c4366c
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> options is that
c4366c
+B<SSL_OP_LEGACY_SERVER_CONNECT> enables initial connections and secure
c4366c
+renegotiation between OpenSSL clients and unpatched servers B<only>, while
c4366c
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> allows initial connections
c4366c
+and renegotiation between OpenSSL and unpatched clients or servers.
c4366c
+
c4366c
 =head1 RETURN VALUES
c4366c
 
c4366c
 SSL_CTX_set_options() and SSL_set_options() return the new options bitmask
c4366c
 after adding B<options>.
c4366c
 
c4366c
+SSL_CTX_clear_options() and SSL_clear_options() return the new options bitmask
c4366c
+after clearing B<options>.
c4366c
+
c4366c
 SSL_CTX_get_options() and SSL_get_options() return the current bitmask.
c4366c
 
c4366c
+SSL_get_secure_renegotiation_support() returns 1 is the peer supports
c4366c
+secure renegotiation and 0 if it does not.
c4366c
+
c4366c
 =head1 SEE ALSO
c4366c
 
c4366c
 L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>, L<SSL_clear(3)|SSL_clear(3)>,
c4366c
@@ -232,4 +339,11 @@ Versions up to OpenSSL 0.9.6c do not inc
c4366c
 can be disabled with this option (in OpenSSL 0.9.6d, it was always
c4366c
 enabled).
c4366c
 
c4366c
+SSL_CTX_clear_options() and SSL_clear_options() were first added in OpenSSL
c4366c
+0.9.8m.
c4366c
+
c4366c
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>, B<SSL_OP_LEGACY_SERVER_CONNECT>
c4366c
+and the function SSL_get_secure_renegotiation_support() were first added in
c4366c
+OpenSSL 0.9.8m.
c4366c
+
c4366c
 =cut
c4366c
diff -up openssl-fips-0.9.8e/ssl/d1_both.c.reneg openssl-fips-0.9.8e/ssl/d1_both.c
c4366c
--- openssl-fips-0.9.8e/ssl/d1_both.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/d1_both.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -750,6 +750,24 @@ int dtls1_send_finished(SSL *s, int a, i
c4366c
 		p+=i;
c4366c
 		l=i;
c4366c
 
c4366c
+	/* Copy the finished so we can use it for
c4366c
+	 * renegotiation checks
c4366c
+	 */
c4366c
+	if(s->type == SSL_ST_CONNECT)
c4366c
+		{
c4366c
+		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
c4366c
+		memcpy(s->s3->previous_client_finished, 
c4366c
+		       s->s3->tmp.finish_md, i);
c4366c
+		s->s3->previous_client_finished_len=i;
c4366c
+		}
c4366c
+	else
c4366c
+		{
c4366c
+		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
c4366c
+		memcpy(s->s3->previous_server_finished, 
c4366c
+		       s->s3->tmp.finish_md, i);
c4366c
+		s->s3->previous_server_finished_len=i;
c4366c
+		}
c4366c
+
c4366c
 #ifdef OPENSSL_SYS_WIN16
c4366c
 		/* MSVC 1.5 does not clear the top bytes of the word unless
c4366c
 		 * I do this.
c4366c
diff -up openssl-fips-0.9.8e/ssl/d1_clnt.c.reneg openssl-fips-0.9.8e/ssl/d1_clnt.c
c4366c
--- openssl-fips-0.9.8e/ssl/d1_clnt.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/d1_clnt.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -621,7 +621,13 @@ int dtls1_client_hello(SSL *s)
c4366c
 			*(p++)=comp->id;
c4366c
 			}
c4366c
 		*(p++)=0; /* Add the NULL method */
c4366c
-		
c4366c
+
c4366c
+		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
c4366c
+			{
c4366c
+			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
c4366c
+			goto err;
c4366c
+			}
c4366c
+
c4366c
 		l=(p-d);
c4366c
 		d=buf;
c4366c
 
c4366c
diff -up openssl-fips-0.9.8e/ssl/d1_srvr.c.reneg openssl-fips-0.9.8e/ssl/d1_srvr.c
c4366c
--- openssl-fips-0.9.8e/ssl/d1_srvr.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/d1_srvr.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -267,7 +267,6 @@ int dtls1_accept(SSL *s)
c4366c
 			s->shutdown=0;
c4366c
 			ret=ssl3_get_client_hello(s);
c4366c
 			if (ret <= 0) goto end;
c4366c
-			s->new_session = 2;
c4366c
 
c4366c
 			if ( s->d1->send_cookie)
c4366c
 				s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A;
c4366c
@@ -293,6 +292,7 @@ int dtls1_accept(SSL *s)
c4366c
 			
c4366c
 		case SSL3_ST_SW_SRVR_HELLO_A:
c4366c
 		case SSL3_ST_SW_SRVR_HELLO_B:
c4366c
+			s->new_session = 2;
c4366c
 			ret=dtls1_send_server_hello(s);
c4366c
 			if (ret <= 0) goto end;
c4366c
 
c4366c
@@ -713,6 +713,8 @@ int dtls1_send_server_hello(SSL *s)
c4366c
 		p+=sl;
c4366c
 
c4366c
 		/* put the cipher */
c4366c
+		if (s->s3->tmp.new_cipher == NULL)
c4366c
+			return -1;
c4366c
 		i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
c4366c
 		p+=i;
c4366c
 
c4366c
@@ -726,13 +728,21 @@ int dtls1_send_server_hello(SSL *s)
c4366c
 			*(p++)=s->s3->tmp.new_compression->id;
c4366c
 #endif
c4366c
 
c4366c
+#ifndef OPENSSL_NO_TLSEXT
c4366c
+		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
c4366c
+			{
c4366c
+			SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
c4366c
+			return -1;
c4366c
+			}
c4366c
+#endif
c4366c
+
c4366c
 		/* do the header */
c4366c
 		l=(p-d);
c4366c
 		d=buf;
c4366c
 
c4366c
 		d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l);
c4366c
 
c4366c
-		s->state=SSL3_ST_CW_CLNT_HELLO_B;
c4366c
+		s->state=SSL3_ST_SW_SRVR_HELLO_B;
c4366c
 		/* number of bytes to write */
c4366c
 		s->init_num=p-buf;
c4366c
 		s->init_off=0;
c4366c
@@ -741,7 +751,7 @@ int dtls1_send_server_hello(SSL *s)
c4366c
 		dtls1_buffer_message(s, 0);
c4366c
 		}
c4366c
 
c4366c
-	/* SSL3_ST_CW_CLNT_HELLO_B */
c4366c
+	/* SSL3_ST_SW_SRVR_HELLO_B */
c4366c
 	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
c4366c
 	}
c4366c
 
c4366c
@@ -765,7 +775,7 @@ int dtls1_send_server_done(SSL *s)
c4366c
 		dtls1_buffer_message(s, 0);
c4366c
 		}
c4366c
 
c4366c
-	/* SSL3_ST_CW_CLNT_HELLO_B */
c4366c
+	/* SSL3_ST_SW_SRVR_DONE_B */
c4366c
 	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
c4366c
 	}
c4366c
 
c4366c
diff -up openssl-fips-0.9.8e/ssl/Makefile.reneg openssl-fips-0.9.8e/ssl/Makefile
c4366c
--- openssl-fips-0.9.8e/ssl/Makefile.reneg	2007-08-01 13:33:16.000000000 +0200
c4366c
+++ openssl-fips-0.9.8e/ssl/Makefile	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -30,7 +30,7 @@ LIBSRC=	\
c4366c
 	ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
c4366c
 	ssl_ciph.c ssl_stat.c ssl_rsa.c \
c4366c
 	ssl_asn1.c ssl_txt.c ssl_algs.c \
c4366c
-	bio_ssl.c ssl_err.c kssl.c
c4366c
+	bio_ssl.c ssl_err.c kssl.c t1_reneg.c
c4366c
 LIBOBJ= \
c4366c
 	s2_meth.o  s2_srvr.o  s2_clnt.o  s2_lib.o  s2_enc.o s2_pkt.o \
c4366c
 	s3_meth.o  s3_srvr.o  s3_clnt.o  s3_lib.o  s3_enc.o s3_pkt.o s3_both.o \
c4366c
@@ -41,7 +41,7 @@ LIBOBJ= \
c4366c
 	ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
c4366c
 	ssl_ciph.o ssl_stat.o ssl_rsa.o \
c4366c
 	ssl_asn1.o ssl_txt.o ssl_algs.o \
c4366c
-	bio_ssl.o ssl_err.o kssl.o
c4366c
+	bio_ssl.o ssl_err.o kssl.o t1_reneg.o
c4366c
 
c4366c
 SRC= $(LIBSRC)
c4366c
 
c4366c
diff -up openssl-fips-0.9.8e/ssl/ssl_err.c.reneg openssl-fips-0.9.8e/ssl/ssl_err.c
c4366c
--- openssl-fips-0.9.8e/ssl/ssl_err.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/ssl_err.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -168,8 +168,12 @@ static ERR_STRING_DATA SSL_str_functs[]=
c4366c
 {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK),	"SSL3_SETUP_KEY_BLOCK"},
c4366c
 {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES),	"SSL3_WRITE_BYTES"},
c4366c
 {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING),	"SSL3_WRITE_PENDING"},
c4366c
+{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT),	"SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
c4366c
+{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT),	"SSL_ADD_CLIENTHELLO_TLSEXT"},
c4366c
 {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK),	"SSL_add_dir_cert_subjects_to_stack"},
c4366c
 {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK),	"SSL_add_file_cert_subjects_to_stack"},
c4366c
+{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT),	"SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"},
c4366c
+{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT),	"SSL_ADD_SERVERHELLO_TLSEXT"},
c4366c
 {ERR_FUNC(SSL_F_SSL_BAD_METHOD),	"SSL_BAD_METHOD"},
c4366c
 {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST),	"SSL_BYTES_TO_CIPHER_LIST"},
c4366c
 {ERR_FUNC(SSL_F_SSL_CERT_DUP),	"SSL_CERT_DUP"},
c4366c
@@ -208,6 +212,10 @@ static ERR_STRING_DATA SSL_str_functs[]=
c4366c
 {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER),	"SSL_INIT_WBIO_BUFFER"},
c4366c
 {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE),	"SSL_load_client_CA_file"},
c4366c
 {ERR_FUNC(SSL_F_SSL_NEW),	"SSL_new"},
c4366c
+{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT),	"SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"},
c4366c
+{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT),	"SSL_PARSE_CLIENTHELLO_TLSEXT"},
c4366c
+{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT),	"SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"},
c4366c
+{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT),	"SSL_PARSE_SERVERHELLO_TLSEXT"},
c4366c
 {ERR_FUNC(SSL_F_SSL_PEEK),	"SSL_peek"},
c4366c
 {ERR_FUNC(SSL_F_SSL_READ),	"SSL_read"},
c4366c
 {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT),	"SSL_RSA_PRIVATE_DECRYPT"},
c4366c
@@ -371,6 +379,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
c4366c
 {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"},
c4366c
 {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"},
c4366c
 {ERR_REASON(SSL_R_NO_PUBLICKEY)          ,"no publickey"},
c4366c
+{ERR_REASON(SSL_R_NO_RENEGOTIATION)      ,"no renegotiation"},
c4366c
 {ERR_REASON(SSL_R_NO_SHARED_CIPHER)      ,"no shared cipher"},
c4366c
 {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK)    ,"no verify callback"},
c4366c
 {ERR_REASON(SSL_R_NULL_SSL_CTX)          ,"null ssl ctx"},
c4366c
@@ -378,6 +387,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
c4366c
 {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),"old session cipher not returned"},
c4366c
 {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),"only tls allowed in fips mode"},
c4366c
 {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG),"packet length too long"},
c4366c
+{ERR_REASON(SSL_R_PARSE_TLSEXT)          ,"parse tlsext"},
c4366c
 {ERR_REASON(SSL_R_PATH_TOO_LONG)         ,"path too long"},
c4366c
 {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE),"peer did not return a certificate"},
c4366c
 {ERR_REASON(SSL_R_PEER_ERROR)            ,"peer error"},
c4366c
@@ -397,10 +407,14 @@ static ERR_STRING_DATA SSL_str_reasons[]
c4366c
 {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH),"record length mismatch"},
c4366c
 {ERR_REASON(SSL_R_RECORD_TOO_LARGE)      ,"record too large"},
c4366c
 {ERR_REASON(SSL_R_RECORD_TOO_SMALL)      ,"record too small"},
c4366c
+{ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG),"renegotiate ext too long"},
c4366c
+{ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),"renegotiation encoding err"},
c4366c
+{ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH),"renegotiation mismatch"},
c4366c
 {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING),"required cipher missing"},
c4366c
 {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse cert length not zero"},
c4366c
 {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse cert type not zero"},
c4366c
 {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse cipher list not zero"},
c4366c
+{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
c4366c
 {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
c4366c
 {ERR_REASON(SSL_R_SHORT_READ)            ,"short read"},
c4366c
 {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
c4366c
@@ -466,6 +480,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
c4366c
 {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE),"unknown remote error type"},
c4366c
 {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION)   ,"unknown ssl version"},
c4366c
 {ERR_REASON(SSL_R_UNKNOWN_STATE)         ,"unknown state"},
c4366c
+{ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),"unsafe legacy renegotiation disabled"},
c4366c
 {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
c4366c
 {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
c4366c
 {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),"unsupported elliptic curve"},
c4366c
diff -up openssl-fips-0.9.8e/ssl/ssl.h.reneg openssl-fips-0.9.8e/ssl/ssl.h
c4366c
--- openssl-fips-0.9.8e/ssl/ssl.h.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/ssl.h	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -480,6 +480,8 @@ typedef struct ssl_session_st
c4366c
 
c4366c
 #define SSL_OP_MICROSOFT_SESS_ID_BUG			0x00000001L
c4366c
 #define SSL_OP_NETSCAPE_CHALLENGE_BUG			0x00000002L
c4366c
+/* Allow initial connection to servers that don't support RI */
c4366c
+#define SSL_OP_LEGACY_SERVER_CONNECT			0x00000004L
c4366c
 #define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG		0x00000008L /* can break some security expectations */
c4366c
 #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG		0x00000010L
c4366c
 #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER		0x00000020L
c4366c
@@ -506,6 +508,8 @@ typedef struct ssl_session_st
c4366c
 
c4366c
 /* As server, disallow session resumption on renegotiation */
c4366c
 #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION	0x00010000L
c4366c
+/* Permit unsafe legacy renegotiation */
c4366c
+#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION	0x00040000L
c4366c
 /* If set, always create a new key when using tmp_ecdh parameters */
c4366c
 #define SSL_OP_SINGLE_ECDH_USE				0x00080000L
c4366c
 /* If set, always create a new key when using tmp_dh parameters */
c4366c
@@ -554,17 +558,25 @@ typedef struct ssl_session_st
c4366c
 
c4366c
 #define SSL_CTX_set_options(ctx,op) \
c4366c
 	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
c4366c
+#define SSL_CTX_clear_options(ctx,op) \
c4366c
+	SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
c4366c
 #define SSL_CTX_get_options(ctx) \
c4366c
 	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
c4366c
 #define SSL_set_options(ssl,op) \
c4366c
 	SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
c4366c
+#define SSL_clear_options(ssl,op) \
c4366c
+	SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
c4366c
 #define SSL_get_options(ssl) \
c4366c
         SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)
c4366c
 
c4366c
 #define SSL_CTX_set_mode(ctx,op) \
c4366c
 	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
c4366c
+#define SSL_CTX_clear_mode(ctx,op) \
c4366c
+	SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL)
c4366c
 #define SSL_CTX_get_mode(ctx) \
c4366c
 	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
c4366c
+#define SSL_clear_mode(ssl,op) \
c4366c
+	SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL)
c4366c
 #define SSL_set_mode(ssl,op) \
c4366c
 	SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
c4366c
 #define SSL_get_mode(ssl) \
c4366c
@@ -572,6 +584,8 @@ typedef struct ssl_session_st
c4366c
 #define SSL_set_mtu(ssl, mtu) \
c4366c
         SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
c4366c
 
c4366c
+#define SSL_get_secure_renegotiation_support(ssl) \
c4366c
+	SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
c4366c
 
c4366c
 void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
c4366c
 void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
c4366c
@@ -1189,6 +1203,10 @@ size_t SSL_get_peer_finished(const SSL *
c4366c
 #define SSL_CTRL_GET_MAX_CERT_LIST		50
c4366c
 #define SSL_CTRL_SET_MAX_CERT_LIST		51
c4366c
 
c4366c
+#define SSL_CTRL_GET_RI_SUPPORT			76
c4366c
+#define SSL_CTRL_CLEAR_OPTIONS			77
c4366c
+#define SSL_CTRL_CLEAR_MODE			78
c4366c
+
c4366c
 #define SSL_session_reused(ssl) \
c4366c
 	SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
c4366c
 #define SSL_num_renegotiations(ssl) \
c4366c
@@ -1650,8 +1668,12 @@ void ERR_load_SSL_strings(void);
c4366c
 #define SSL_F_SSL3_SETUP_KEY_BLOCK			 157
c4366c
 #define SSL_F_SSL3_WRITE_BYTES				 158
c4366c
 #define SSL_F_SSL3_WRITE_PENDING			 159
c4366c
+#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT	 285
c4366c
+#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 272
c4366c
 #define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK	 215
c4366c
 #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK	 216
c4366c
+#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT	 286
c4366c
+#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 273
c4366c
 #define SSL_F_SSL_BAD_METHOD				 160
c4366c
 #define SSL_F_SSL_BYTES_TO_CIPHER_LIST			 161
c4366c
 #define SSL_F_SSL_CERT_DUP				 221
c4366c
@@ -1690,6 +1712,10 @@ void ERR_load_SSL_strings(void);
c4366c
 #define SSL_F_SSL_INIT_WBIO_BUFFER			 184
c4366c
 #define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
c4366c
 #define SSL_F_SSL_NEW					 186
c4366c
+#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT	 287
c4366c
+#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT		 290
c4366c
+#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 289
c4366c
+#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 291
c4366c
 #define SSL_F_SSL_PEEK					 270
c4366c
 #define SSL_F_SSL_READ					 223
c4366c
 #define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
c4366c
@@ -1850,6 +1876,7 @@ void ERR_load_SSL_strings(void);
c4366c
 #define SSL_R_NO_PRIVATE_KEY_ASSIGNED			 190
c4366c
 #define SSL_R_NO_PROTOCOLS_AVAILABLE			 191
c4366c
 #define SSL_R_NO_PUBLICKEY				 192
c4366c
+#define SSL_R_NO_RENEGOTIATION				 319
c4366c
 #define SSL_R_NO_SHARED_CIPHER				 193
c4366c
 #define SSL_R_NO_VERIFY_CALLBACK			 194
c4366c
 #define SSL_R_NULL_SSL_CTX				 195
c4366c
@@ -1857,6 +1884,7 @@ void ERR_load_SSL_strings(void);
c4366c
 #define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED		 197
c4366c
 #define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE		 297
c4366c
 #define SSL_R_PACKET_LENGTH_TOO_LONG			 198
c4366c
+#define SSL_R_PARSE_TLSEXT				 223
c4366c
 #define SSL_R_PATH_TOO_LONG				 270
c4366c
 #define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE		 199
c4366c
 #define SSL_R_PEER_ERROR				 200
c4366c
@@ -1876,10 +1904,14 @@ void ERR_load_SSL_strings(void);
c4366c
 #define SSL_R_RECORD_LENGTH_MISMATCH			 213
c4366c
 #define SSL_R_RECORD_TOO_LARGE				 214
c4366c
 #define SSL_R_RECORD_TOO_SMALL				 298
c4366c
+#define SSL_R_RENEGOTIATE_EXT_TOO_LONG			 320
c4366c
+#define SSL_R_RENEGOTIATION_ENCODING_ERR		 321
c4366c
+#define SSL_R_RENEGOTIATION_MISMATCH			 322
c4366c
 #define SSL_R_REQUIRED_CIPHER_MISSING			 215
c4366c
 #define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO		 216
c4366c
 #define SSL_R_REUSE_CERT_TYPE_NOT_ZERO			 217
c4366c
 #define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO		 218
c4366c
+#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 324
c4366c
 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
c4366c
 #define SSL_R_SHORT_READ				 219
c4366c
 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
c4366c
@@ -1945,6 +1977,7 @@ void ERR_load_SSL_strings(void);
c4366c
 #define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE			 253
c4366c
 #define SSL_R_UNKNOWN_SSL_VERSION			 254
c4366c
 #define SSL_R_UNKNOWN_STATE				 255
c4366c
+#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED	 323
c4366c
 #define SSL_R_UNSUPPORTED_CIPHER			 256
c4366c
 #define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 257
c4366c
 #define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE		 315
c4366c
diff -up openssl-fips-0.9.8e/ssl/ssl_lib.c.reneg openssl-fips-0.9.8e/ssl/ssl_lib.c
c4366c
--- openssl-fips-0.9.8e/ssl/ssl_lib.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/ssl_lib.c	2010-02-18 16:10:30.000000000 +0100
c4366c
@@ -958,8 +958,12 @@ long SSL_ctrl(SSL *s,int cmd,long larg,v
c4366c
 
c4366c
 	case SSL_CTRL_OPTIONS:
c4366c
 		return(s->options|=larg);
c4366c
+	case SSL_CTRL_CLEAR_OPTIONS:
c4366c
+		return(s->options&=~larg);
c4366c
 	case SSL_CTRL_MODE:
c4366c
 		return(s->mode|=larg);
c4366c
+	case SSL_CTRL_CLEAR_MODE:
c4366c
+		return(s->mode &=~larg);
c4366c
 	case SSL_CTRL_GET_MAX_CERT_LIST:
c4366c
 		return(s->max_cert_list);
c4366c
 	case SSL_CTRL_SET_MAX_CERT_LIST:
c4366c
@@ -973,6 +977,10 @@ long SSL_ctrl(SSL *s,int cmd,long larg,v
c4366c
 			return larg;
c4366c
 			}
c4366c
 		return 0;
c4366c
+	case SSL_CTRL_GET_RI_SUPPORT:
c4366c
+		if (s->s3)
c4366c
+			return s->s3->send_connection_binding;
c4366c
+		else return 0;
c4366c
 	default:
c4366c
 		return(s->method->ssl_ctrl(s,cmd,larg,parg));
c4366c
 		}
c4366c
@@ -1059,8 +1067,12 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,l
c4366c
 		return(ctx->stats.sess_cache_full);
c4366c
 	case SSL_CTRL_OPTIONS:
c4366c
 		return(ctx->options|=larg);
c4366c
+	case SSL_CTRL_CLEAR_OPTIONS:
c4366c
+		return(ctx->options&=~larg);
c4366c
 	case SSL_CTRL_MODE:
c4366c
 		return(ctx->mode|=larg);
c4366c
+	case SSL_CTRL_CLEAR_MODE:
c4366c
+		return(ctx->mode&=~larg);
c4366c
 	default:
c4366c
 		return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
c4366c
 		}
c4366c
@@ -1257,6 +1269,22 @@ int ssl_cipher_list_to_bytes(SSL *s,STAC
c4366c
 		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
c4366c
 		p+=j;
c4366c
 		}
c4366c
+	/* If p == q, no ciphers and caller indicates an error. Otherwise
c4366c
+	 * add SCSV if not renegotiating.
c4366c
+	 */
c4366c
+	if (p != q && !s->new_session)
c4366c
+		{
c4366c
+		static SSL_CIPHER scsv =
c4366c
+			{
c4366c
+			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0,
c4366c
+			};
c4366c
+		j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
c4366c
+		p+=j;
c4366c
+#ifdef OPENSSL_RI_DEBUG
c4366c
+		fprintf(stderr, "SCSV sent by client\n");
c4366c
+#endif
c4366c
+		}
c4366c
+
c4366c
 	return(p-q);
c4366c
 	}
c4366c
 
c4366c
@@ -1266,6 +1294,8 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe
c4366c
 	SSL_CIPHER *c;
c4366c
 	STACK_OF(SSL_CIPHER) *sk;
c4366c
 	int i,n;
c4366c
+	if (s->s3)
c4366c
+		s->s3->send_connection_binding = 0;
c4366c
 
c4366c
 	n=ssl_put_cipher_by_char(s,NULL,NULL);
c4366c
 	if ((num%n) != 0)
c4366c
@@ -1283,6 +1313,26 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe
c4366c
 
c4366c
 	for (i=0; i
c4366c
 		{
c4366c
+		/* Check for SCSV */
c4366c
+		if (s->s3 && (n != 3 || !p[0]) &&
c4366c
+			(p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
c4366c
+			(p[n-1] == (SSL3_CK_SCSV & 0xff)))
c4366c
+			{
c4366c
+			/* SCSV fatal if renegotiating */
c4366c
+			if (s->new_session)
c4366c
+				{
c4366c
+				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
c4366c
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); 
c4366c
+				goto err;
c4366c
+				}
c4366c
+			s->s3->send_connection_binding = 1;
c4366c
+			p += n;
c4366c
+#ifdef OPENSSL_RI_DEBUG
c4366c
+			fprintf(stderr, "SCSV received by server\n");
c4366c
+#endif
c4366c
+			continue;
c4366c
+			}
c4366c
+
c4366c
 		c=ssl_get_cipher_by_char(s,p);
c4366c
 		p+=n;
c4366c
 		if (c != NULL)
c4366c
@@ -1461,6 +1511,11 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
c4366c
 	ret->extra_certs=NULL;
c4366c
 	ret->comp_methods=SSL_COMP_get_compression_methods();
c4366c
 
c4366c
+	/* Default is to connect to non-RI servers. When RI is more widely
c4366c
+	 * deployed might change this.
c4366c
+	 */
c4366c
+	ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
c4366c
+
c4366c
 	return(ret);
c4366c
 err:
c4366c
 	SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
c4366c
diff -up openssl-fips-0.9.8e/ssl/ssl_locl.h.reneg openssl-fips-0.9.8e/ssl/ssl_locl.h
c4366c
--- openssl-fips-0.9.8e/ssl/ssl_locl.h.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/ssl_locl.h	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -934,5 +934,17 @@ int check_srvr_ecc_cert_and_alg(X509 *x,
c4366c
 
c4366c
 SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
c4366c
 
c4366c
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
c4366c
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
c4366c
+int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
c4366c
+int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
c4366c
+int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
c4366c
+					int maxlen);
c4366c
+int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
c4366c
+					  int *al);
c4366c
+int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
c4366c
+					int maxlen);
c4366c
+int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
c4366c
+					  int *al);
c4366c
 
c4366c
 #endif
c4366c
diff -up openssl-fips-0.9.8e/ssl/ssl3.h.reneg openssl-fips-0.9.8e/ssl/ssl3.h
c4366c
--- openssl-fips-0.9.8e/ssl/ssl3.h.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/ssl3.h	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -129,6 +129,9 @@
c4366c
 extern "C" {
c4366c
 #endif
c4366c
 
c4366c
+/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
c4366c
+#define SSL3_CK_SCSV				0x030000FF
c4366c
+
c4366c
 #define SSL3_CK_RSA_NULL_MD5			0x03000001
c4366c
 #define SSL3_CK_RSA_NULL_SHA			0x03000002
c4366c
 #define SSL3_CK_RSA_RC4_40_MD5 			0x03000003
c4366c
@@ -437,6 +440,12 @@ typedef struct ssl3_state_st
c4366c
 		int cert_request;
c4366c
 		} tmp;
c4366c
 
c4366c
+        /* Connection binding to prevent renegotiation attacks */
c4366c
+        unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
c4366c
+        unsigned char previous_client_finished_len;
c4366c
+        unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
c4366c
+        unsigned char previous_server_finished_len;
c4366c
+        int send_connection_binding; /* TODOEKR */
c4366c
 	} SSL3_STATE;
c4366c
 
c4366c
 
c4366c
diff -up openssl-fips-0.9.8e/ssl/s23_clnt.c.reneg openssl-fips-0.9.8e/ssl/s23_clnt.c
c4366c
--- openssl-fips-0.9.8e/ssl/s23_clnt.c.reneg	2007-03-22 01:39:13.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/s23_clnt.c	2010-02-18 16:07:51.000000000 +0100
c4366c
@@ -368,6 +368,11 @@ static int ssl23_client_hello(SSL *s)
c4366c
 				*(p++)=comp->id;
c4366c
 				}
c4366c
 			*(p++)=0; /* Add the NULL method */
c4366c
+			if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
c4366c
+				{
c4366c
+				SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
c4366c
+				return -1;
c4366c
+				}
c4366c
 			
c4366c
 			l = p-d;
c4366c
 			*p = 42;
c4366c
diff -up openssl-fips-0.9.8e/ssl/s3_both.c.reneg openssl-fips-0.9.8e/ssl/s3_both.c
c4366c
--- openssl-fips-0.9.8e/ssl/s3_both.c.reneg	2005-04-26 18:02:39.000000000 +0200
c4366c
+++ openssl-fips-0.9.8e/ssl/s3_both.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -168,6 +168,23 @@ int ssl3_send_finished(SSL *s, int a, in
c4366c
 		p+=i;
c4366c
 		l=i;
c4366c
 
c4366c
+                /* Copy the finished so we can use it for
c4366c
+                   renegotiation checks */
c4366c
+                if(s->type == SSL_ST_CONNECT)
c4366c
+                        {
c4366c
+                         OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
c4366c
+                         memcpy(s->s3->previous_client_finished, 
c4366c
+                             s->s3->tmp.finish_md, i);
c4366c
+                         s->s3->previous_client_finished_len=i;
c4366c
+                        }
c4366c
+                else
c4366c
+                        {
c4366c
+                        OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
c4366c
+                        memcpy(s->s3->previous_server_finished, 
c4366c
+                            s->s3->tmp.finish_md, i);
c4366c
+                        s->s3->previous_server_finished_len=i;
c4366c
+                        }
c4366c
+
c4366c
 #ifdef OPENSSL_SYS_WIN16
c4366c
 		/* MSVC 1.5 does not clear the top bytes of the word unless
c4366c
 		 * I do this.
c4366c
@@ -232,6 +249,23 @@ int ssl3_get_finished(SSL *s, int a, int
c4366c
 		goto f_err;
c4366c
 		}
c4366c
 
c4366c
+        /* Copy the finished so we can use it for
c4366c
+           renegotiation checks */
c4366c
+        if(s->type == SSL_ST_ACCEPT)
c4366c
+                {
c4366c
+                OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
c4366c
+                memcpy(s->s3->previous_client_finished, 
c4366c
+                    s->s3->tmp.peer_finish_md, i);
c4366c
+                s->s3->previous_client_finished_len=i;
c4366c
+                }
c4366c
+        else
c4366c
+                {
c4366c
+                OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
c4366c
+                memcpy(s->s3->previous_server_finished, 
c4366c
+                    s->s3->tmp.peer_finish_md, i);
c4366c
+                s->s3->previous_server_finished_len=i;
c4366c
+                }
c4366c
+
c4366c
 	return(1);
c4366c
 f_err:
c4366c
 	ssl3_send_alert(s,SSL3_AL_FATAL,al);
c4366c
diff -up openssl-fips-0.9.8e/ssl/s3_clnt.c.reneg openssl-fips-0.9.8e/ssl/s3_clnt.c
c4366c
--- openssl-fips-0.9.8e/ssl/s3_clnt.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/s3_clnt.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -601,7 +601,11 @@ int ssl3_client_hello(SSL *s)
c4366c
 			}
c4366c
 #endif
c4366c
 		*(p++)=0; /* Add the NULL method */
c4366c
-		
c4366c
+		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
c4366c
+			{
c4366c
+			SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
c4366c
+			goto err;
c4366c
+			}
c4366c
 		l=(p-d);
c4366c
 		d=buf;
c4366c
 		*(d++)=SSL3_MT_CLIENT_HELLO;
c4366c
@@ -635,7 +639,7 @@ int ssl3_get_server_hello(SSL *s)
c4366c
 		SSL3_ST_CR_SRVR_HELLO_A,
c4366c
 		SSL3_ST_CR_SRVR_HELLO_B,
c4366c
 		-1,
c4366c
-		300, /* ?? */
c4366c
+		1000, /* ?? */
c4366c
 		&ok;;
c4366c
 
c4366c
 	if (!ok) return((int)n);
c4366c
@@ -785,6 +789,17 @@ int ssl3_get_server_hello(SSL *s)
c4366c
 		s->s3->tmp.new_compression=comp;
c4366c
 		}
c4366c
 #endif
c4366c
+	/* TLS extensions - we parse renegotiate extension only */
c4366c
+	if (s->version >= SSL3_VERSION)
c4366c
+		{
c4366c
+		if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al))
c4366c
+			{
c4366c
+			/* 'al' set by ssl_parse_serverhello_tlsext */
c4366c
+			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_PARSE_TLSEXT);
c4366c
+			goto f_err; 
c4366c
+			}
c4366c
+		}
c4366c
+
c4366c
 
c4366c
 	if (p != (d+n))
c4366c
 		{
c4366c
diff -up openssl-fips-0.9.8e/ssl/s3_pkt.c.reneg openssl-fips-0.9.8e/ssl/s3_pkt.c
c4366c
--- openssl-fips-0.9.8e/ssl/s3_pkt.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/s3_pkt.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -1013,7 +1013,25 @@ start:
c4366c
 		 * now try again to obtain the (application) data we were asked for */
c4366c
 		goto start;
c4366c
 		}
c4366c
-
c4366c
+	/* If we are a server and get a client hello when renegotiation isn't
c4366c
+	 * allowed send back a no renegotiation alert and carry on.
c4366c
+	 * WARNING: experimental code, needs reviewing (steve)
c4366c
+	 */
c4366c
+	if (s->server &&
c4366c
+		SSL_is_init_finished(s) &&
c4366c
+    		!s->s3->send_connection_binding &&
c4366c
+		(s->version > SSL3_VERSION) &&
c4366c
+		(s->s3->handshake_fragment_len >= 4) &&
c4366c
+		(s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
c4366c
+		(s->session != NULL) && (s->session->cipher != NULL) &&
c4366c
+		!(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
c4366c
+		
c4366c
+		{
c4366c
+		/*s->s3->handshake_fragment_len = 0;*/
c4366c
+		rr->length = 0;
c4366c
+		ssl3_send_alert(s,SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
c4366c
+		goto start;
c4366c
+		}
c4366c
 	if (s->s3->alert_fragment_len >= 2)
c4366c
 		{
c4366c
 		int alert_level = s->s3->alert_fragment[0];
c4366c
@@ -1043,6 +1061,21 @@ start:
c4366c
 				s->shutdown |= SSL_RECEIVED_SHUTDOWN;
c4366c
 				return(0);
c4366c
 				}
c4366c
+			/* This is a warning but we receive it if we requested
c4366c
+			 * renegotiation and the peer denied it. Terminate with
c4366c
+			 * a fatal alert because if application tried to
c4366c
+			 * renegotiatie it presumably had a good reason and
c4366c
+			 * expects it to succeed.
c4366c
+			 *
c4366c
+			 * In future we might have a renegotiation where we
c4366c
+			 * don't care if the peer refused it where we carry on.
c4366c
+			 */
c4366c
+			else if (alert_descr == SSL_AD_NO_RENEGOTIATION)
c4366c
+				{
c4366c
+				al = SSL_AD_HANDSHAKE_FAILURE;
c4366c
+				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
c4366c
+				goto f_err;
c4366c
+				}
c4366c
 			}
c4366c
 		else if (alert_level == 2) /* fatal */
c4366c
 			{
c4366c
diff -up openssl-fips-0.9.8e/ssl/s3_srvr.c.reneg openssl-fips-0.9.8e/ssl/s3_srvr.c
c4366c
--- openssl-fips-0.9.8e/ssl/s3_srvr.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/s3_srvr.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -248,6 +248,18 @@ int ssl3_accept(SSL *s)
c4366c
 				s->state=SSL3_ST_SR_CLNT_HELLO_A;
c4366c
 				s->ctx->stats.sess_accept++;
c4366c
 				}
c4366c
+			else if (!s->s3->send_connection_binding &&
c4366c
+				!(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
c4366c
+				{
c4366c
+				/* Server attempting to renegotiate with
c4366c
+				 * client that doesn't support secure
c4366c
+				 * renegotiation.
c4366c
+				 */
c4366c
+				SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
c4366c
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
c4366c
+				ret = -1;
c4366c
+				goto end;
c4366c
+				}
c4366c
 			else
c4366c
 				{
c4366c
 				/* s->state == SSL_ST_RENEGOTIATE,
c4366c
@@ -898,6 +910,16 @@ int ssl3_get_client_hello(SSL *s)
c4366c
 		goto f_err;
c4366c
 		}
c4366c
 
c4366c
+	/* TLS extensions - just parsing the renegotiation extension */
c4366c
+	if (s->version >= SSL3_VERSION)
c4366c
+		{
c4366c
+		if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
c4366c
+			{
c4366c
+			/* 'al' set by ssl_parse_clienthello_tlsext */
c4366c
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
c4366c
+			goto f_err;
c4366c
+			}
c4366c
+		}
c4366c
 	/* Worst case, we will use the NULL compression, but if we have other
c4366c
 	 * options, we will now look for them.  We have i-1 compression
c4366c
 	 * algorithms from the client, starting at q. */
c4366c
@@ -1089,20 +1111,24 @@ int ssl3_send_server_hello(SSL *s)
c4366c
 		else
c4366c
 			*(p++)=s->s3->tmp.new_compression->id;
c4366c
 #endif
c4366c
-
c4366c
+		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
c4366c
+			{
c4366c
+			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
c4366c
+			return -1;
c4366c
+			}
c4366c
 		/* do the header */
c4366c
 		l=(p-d);
c4366c
 		d=buf;
c4366c
 		*(d++)=SSL3_MT_SERVER_HELLO;
c4366c
 		l2n3(l,d);
c4366c
 
c4366c
-		s->state=SSL3_ST_CW_CLNT_HELLO_B;
c4366c
+		s->state=SSL3_ST_SW_SRVR_HELLO_B;
c4366c
 		/* number of bytes to write */
c4366c
 		s->init_num=p-buf;
c4366c
 		s->init_off=0;
c4366c
 		}
c4366c
 
c4366c
-	/* SSL3_ST_CW_CLNT_HELLO_B */
c4366c
+	/* SSL3_ST_SW_SRVR_HELLO_B */
c4366c
 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
c4366c
 	}
c4366c
 
c4366c
@@ -1126,7 +1152,7 @@ int ssl3_send_server_done(SSL *s)
c4366c
 		s->init_off=0;
c4366c
 		}
c4366c
 
c4366c
-	/* SSL3_ST_CW_CLNT_HELLO_B */
c4366c
+	/* SSL3_ST_SW_SRVR_DONE_B */
c4366c
 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
c4366c
 	}
c4366c
 
c4366c
diff -up openssl-fips-0.9.8e/ssl/tls1.h.reneg openssl-fips-0.9.8e/ssl/tls1.h
c4366c
--- openssl-fips-0.9.8e/ssl/tls1.h.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/tls1.h	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -97,6 +97,9 @@ extern "C" {
c4366c
 #define TLS1_AD_USER_CANCELLED		90
c4366c
 #define TLS1_AD_NO_RENEGOTIATION	100
c4366c
 
c4366c
+/* Temporary extension type */
c4366c
+#define TLSEXT_TYPE_renegotiate                 0xff01
c4366c
+
c4366c
 /* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
c4366c
  * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see
c4366c
  * s3_lib.c).  We actually treat them like SSL 3.0 ciphers, which we probably
c4366c
diff -up openssl-fips-0.9.8e/ssl/t1_lib.c.reneg openssl-fips-0.9.8e/ssl/t1_lib.c
c4366c
--- openssl-fips-0.9.8e/ssl/t1_lib.c.reneg	2007-01-21 17:07:25.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/t1_lib.c	2010-02-18 16:10:05.000000000 +0100
c4366c
@@ -117,3 +117,202 @@ long tls1_callback_ctrl(SSL *s, int cmd,
c4366c
 	return(0);
c4366c
 	}
c4366c
 #endif
c4366c
+
c4366c
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
c4366c
+	{
c4366c
+	int extdatalen=0;
c4366c
+	unsigned char *ret = p;
c4366c
+
c4366c
+	/* don't add extensions for SSLv3 unless doing secure renegotiation */
c4366c
+	if (s->client_version == SSL3_VERSION
c4366c
+					&& !s->s3->send_connection_binding)
c4366c
+		return p;
c4366c
+
c4366c
+	ret+=2;
c4366c
+
c4366c
+	if (ret>=limit) return NULL; /* this really never occurs, but ... */
c4366c
+ 
c4366c
+        /* Add RI if renegotiating */
c4366c
+        if (s->new_session)
c4366c
+          {
c4366c
+          int el;
c4366c
+          
c4366c
+          if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
c4366c
+              {
c4366c
+              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
c4366c
+              return NULL;
c4366c
+              }
c4366c
+
c4366c
+          if((limit - p - 4 - el) < 0) return NULL;
c4366c
+          
c4366c
+          s2n(TLSEXT_TYPE_renegotiate,ret);
c4366c
+          s2n(el,ret);
c4366c
+
c4366c
+          if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
c4366c
+              {
c4366c
+              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
c4366c
+              return NULL;
c4366c
+              }
c4366c
+
c4366c
+          ret += el;
c4366c
+        }
c4366c
+
c4366c
+	if ((extdatalen = ret-p-2)== 0) 
c4366c
+		return p;
c4366c
+
c4366c
+	s2n(extdatalen,p);
c4366c
+	return ret;
c4366c
+	}
c4366c
+
c4366c
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
c4366c
+	{
c4366c
+	int extdatalen=0;
c4366c
+	unsigned char *ret = p;
c4366c
+
c4366c
+	/* don't add extensions for SSLv3, unless doing secure renegotiation */
c4366c
+	if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
c4366c
+		return p;
c4366c
+	
c4366c
+	ret+=2;
c4366c
+	if (ret>=limit) return NULL; /* this really never occurs, but ... */
c4366c
+
c4366c
+	if(s->s3->send_connection_binding)
c4366c
+        {
c4366c
+          int el;
c4366c
+          
c4366c
+          if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
c4366c
+              {
c4366c
+              SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
c4366c
+              return NULL;
c4366c
+              }
c4366c
+
c4366c
+          if((limit - p - 4 - el) < 0) return NULL;
c4366c
+          
c4366c
+          s2n(TLSEXT_TYPE_renegotiate,ret);
c4366c
+          s2n(el,ret);
c4366c
+
c4366c
+          if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
c4366c
+              {
c4366c
+              SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
c4366c
+              return NULL;
c4366c
+              }
c4366c
+
c4366c
+          ret += el;
c4366c
+        }
c4366c
+
c4366c
+	if ((extdatalen = ret-p-2)== 0) 
c4366c
+		return p;
c4366c
+
c4366c
+	s2n(extdatalen,p);
c4366c
+	return ret;
c4366c
+	}
c4366c
+
c4366c
+int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
c4366c
+	{
c4366c
+	unsigned short type;
c4366c
+	unsigned short size;
c4366c
+	unsigned short len;
c4366c
+	unsigned char *data = *p;
c4366c
+	int renegotiate_seen = 0;
c4366c
+
c4366c
+	if (data >= (d+n-2))
c4366c
+		goto ri_check;
c4366c
+
c4366c
+	n2s(data,len);
c4366c
+
c4366c
+	if (data > (d+n-len)) 
c4366c
+		goto ri_check;
c4366c
+
c4366c
+	while (data <= (d+n-4))
c4366c
+		{
c4366c
+		n2s(data,type);
c4366c
+		n2s(data,size);
c4366c
+
c4366c
+		if (data+size > (d+n))
c4366c
+	   		goto ri_check;
c4366c
+
c4366c
+		if (type == TLSEXT_TYPE_renegotiate)
c4366c
+			{
c4366c
+			if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
c4366c
+				return 0;
c4366c
+			renegotiate_seen = 1;
c4366c
+			}
c4366c
+
c4366c
+		data+=size;		
c4366c
+		}
c4366c
+	*p = data;
c4366c
+
c4366c
+	ri_check:
c4366c
+
c4366c
+	/* Need RI if renegotiating */
c4366c
+
c4366c
+	if (!renegotiate_seen && s->new_session &&
c4366c
+		!(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
c4366c
+		{
c4366c
+		*al = SSL_AD_HANDSHAKE_FAILURE;
c4366c
+	 	SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,
c4366c
+				SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
c4366c
+		return 0;
c4366c
+		}
c4366c
+
c4366c
+	return 1;
c4366c
+	}
c4366c
+
c4366c
+int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
c4366c
+	{
c4366c
+	unsigned short type;
c4366c
+	unsigned short size;
c4366c
+	unsigned short len;  
c4366c
+	unsigned char *data = *p;
c4366c
+	int renegotiate_seen = 0;
c4366c
+
c4366c
+	if (data >= (d+n-2))
c4366c
+		goto ri_check;
c4366c
+
c4366c
+	n2s(data,len);
c4366c
+
c4366c
+	while(data <= (d+n-4))
c4366c
+		{
c4366c
+		n2s(data,type);
c4366c
+		n2s(data,size);
c4366c
+
c4366c
+		if (data+size > (d+n))
c4366c
+	   		goto ri_check;
c4366c
+		if (type == TLSEXT_TYPE_renegotiate)
c4366c
+			{
c4366c
+			if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
c4366c
+				return 0;
c4366c
+			renegotiate_seen = 1;
c4366c
+			}
c4366c
+		data+=size;		
c4366c
+		}
c4366c
+
c4366c
+	if (data != d+n)
c4366c
+		{
c4366c
+		*al = SSL_AD_DECODE_ERROR;
c4366c
+		return 0;
c4366c
+		}
c4366c
+
c4366c
+	*p = data;
c4366c
+
c4366c
+	ri_check:
c4366c
+
c4366c
+	/* Determine if we need to see RI. Strictly speaking if we want to
c4366c
+	 * avoid an attack we should *always* see RI even on initial server
c4366c
+	 * hello because the client doesn't see any renegotiation during an
c4366c
+	 * attack. However this would mean we could not connect to any server
c4366c
+	 * which doesn't support RI so for the immediate future tolerate RI
c4366c
+	 * absence on initial connect only.
c4366c
+	 */
c4366c
+	if (!renegotiate_seen
c4366c
+		&& !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
c4366c
+		&& !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
c4366c
+		{
c4366c
+		*al = SSL_AD_HANDSHAKE_FAILURE;
c4366c
+		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT,
c4366c
+				SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
c4366c
+		return 0;
c4366c
+		}
c4366c
+
c4366c
+	return 1;
c4366c
+	}
c4366c
diff -up openssl-fips-0.9.8e/ssl/t1_reneg.c.reneg openssl-fips-0.9.8e/ssl/t1_reneg.c
c4366c
--- openssl-fips-0.9.8e/ssl/t1_reneg.c.reneg	2010-02-18 15:58:31.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/ssl/t1_reneg.c	2010-02-18 15:58:31.000000000 +0100
c4366c
@@ -0,0 +1,292 @@
c4366c
+/* ssl/t1_reneg.c */
c4366c
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
c4366c
+ * All rights reserved.
c4366c
+ *
c4366c
+ * This package is an SSL implementation written
c4366c
+ * by Eric Young (eay@cryptsoft.com).
c4366c
+ * The implementation was written so as to conform with Netscapes SSL.
c4366c
+ * 
c4366c
+ * This library is free for commercial and non-commercial use as long as
c4366c
+ * the following conditions are aheared to.  The following conditions
c4366c
+ * apply to all code found in this distribution, be it the RC4, RSA,
c4366c
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
c4366c
+ * included with this distribution is covered by the same copyright terms
c4366c
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
c4366c
+ * 
c4366c
+ * Copyright remains Eric Young's, and as such any Copyright notices in
c4366c
+ * the code are not to be removed.
c4366c
+ * If this package is used in a product, Eric Young should be given attribution
c4366c
+ * as the author of the parts of the library used.
c4366c
+ * This can be in the form of a textual message at program startup or
c4366c
+ * in documentation (online or textual) provided with the package.
c4366c
+ * 
c4366c
+ * Redistribution and use in source and binary forms, with or without
c4366c
+ * modification, are permitted provided that the following conditions
c4366c
+ * are met:
c4366c
+ * 1. Redistributions of source code must retain the copyright
c4366c
+ *    notice, this list of conditions and the following disclaimer.
c4366c
+ * 2. Redistributions in binary form must reproduce the above copyright
c4366c
+ *    notice, this list of conditions and the following disclaimer in the
c4366c
+ *    documentation and/or other materials provided with the distribution.
c4366c
+ * 3. All advertising materials mentioning features or use of this software
c4366c
+ *    must display the following acknowledgement:
c4366c
+ *    "This product includes cryptographic software written by
c4366c
+ *     Eric Young (eay@cryptsoft.com)"
c4366c
+ *    The word 'cryptographic' can be left out if the rouines from the library
c4366c
+ *    being used are not cryptographic related :-).
c4366c
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
c4366c
+ *    the apps directory (application code) you must include an acknowledgement:
c4366c
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
c4366c
+ * 
c4366c
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
c4366c
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
c4366c
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
c4366c
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
c4366c
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
c4366c
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
c4366c
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
c4366c
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
c4366c
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
c4366c
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
c4366c
+ * SUCH DAMAGE.
c4366c
+ * 
c4366c
+ * The licence and distribution terms for any publically available version or
c4366c
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
c4366c
+ * copied and put under another distribution licence
c4366c
+ * [including the GNU Public Licence.]
c4366c
+ */
c4366c
+/* ====================================================================
c4366c
+ * Copyright (c) 1998-2009 The OpenSSL Project.  All rights reserved.
c4366c
+ *
c4366c
+ * Redistribution and use in source and binary forms, with or without
c4366c
+ * modification, are permitted provided that the following conditions
c4366c
+ * are met:
c4366c
+ *
c4366c
+ * 1. Redistributions of source code must retain the above copyright
c4366c
+ *    notice, this list of conditions and the following disclaimer. 
c4366c
+ *
c4366c
+ * 2. Redistributions in binary form must reproduce the above copyright
c4366c
+ *    notice, this list of conditions and the following disclaimer in
c4366c
+ *    the documentation and/or other materials provided with the
c4366c
+ *    distribution.
c4366c
+ *
c4366c
+ * 3. All advertising materials mentioning features or use of this
c4366c
+ *    software must display the following acknowledgment:
c4366c
+ *    "This product includes software developed by the OpenSSL Project
c4366c
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
c4366c
+ *
c4366c
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
c4366c
+ *    endorse or promote products derived from this software without
c4366c
+ *    prior written permission. For written permission, please contact
c4366c
+ *    openssl-core@openssl.org.
c4366c
+ *
c4366c
+ * 5. Products derived from this software may not be called "OpenSSL"
c4366c
+ *    nor may "OpenSSL" appear in their names without prior written
c4366c
+ *    permission of the OpenSSL Project.
c4366c
+ *
c4366c
+ * 6. Redistributions of any form whatsoever must retain the following
c4366c
+ *    acknowledgment:
c4366c
+ *    "This product includes software developed by the OpenSSL Project
c4366c
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
c4366c
+ *
c4366c
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
c4366c
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
c4366c
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
c4366c
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
c4366c
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
c4366c
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
c4366c
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
c4366c
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
c4366c
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
c4366c
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
c4366c
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
c4366c
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
c4366c
+ * ====================================================================
c4366c
+ *
c4366c
+ * This product includes cryptographic software written by Eric Young
c4366c
+ * (eay@cryptsoft.com).  This product includes software written by Tim
c4366c
+ * Hudson (tjh@cryptsoft.com).
c4366c
+ *
c4366c
+ */
c4366c
+#include <stdio.h>
c4366c
+#include <openssl/objects.h>
c4366c
+#include "ssl_locl.h"
c4366c
+
c4366c
+/* Add the client's renegotiation binding */
c4366c
+int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
c4366c
+					int maxlen)
c4366c
+    {
c4366c
+    if(p)
c4366c
+        {
c4366c
+	if((s->s3->previous_client_finished_len+1) > maxlen)
c4366c
+            {
c4366c
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
c4366c
+            return 0;
c4366c
+            }
c4366c
+            
c4366c
+        /* Length byte */
c4366c
+	*p = s->s3->previous_client_finished_len;
c4366c
+        p++;
c4366c
+
c4366c
+        memcpy(p, s->s3->previous_client_finished,
c4366c
+	       s->s3->previous_client_finished_len);
c4366c
+#ifdef OPENSSL_RI_DEBUG
c4366c
+    fprintf(stderr, "%s RI extension sent by client\n",
c4366c
+		s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
c4366c
+#endif
c4366c
+        }
c4366c
+    
c4366c
+    *len=s->s3->previous_client_finished_len + 1;
c4366c
+
c4366c
+ 
c4366c
+    return 1;
c4366c
+    }
c4366c
+
c4366c
+/* Parse the client's renegotiation binding and abort if it's not
c4366c
+   right */
c4366c
+int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
c4366c
+					  int *al)
c4366c
+    {
c4366c
+    int ilen;
c4366c
+
c4366c
+    /* Parse the length byte */
c4366c
+    if(len < 1)
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
c4366c
+        *al=SSL_AD_ILLEGAL_PARAMETER;
c4366c
+        return 0;
c4366c
+        }
c4366c
+    ilen = *d;
c4366c
+    d++;
c4366c
+
c4366c
+    /* Consistency check */
c4366c
+    if((ilen+1) != len)
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
c4366c
+        *al=SSL_AD_ILLEGAL_PARAMETER;
c4366c
+        return 0;
c4366c
+        }
c4366c
+
c4366c
+    /* Check that the extension matches */
c4366c
+    if(ilen != s->s3->previous_client_finished_len)
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
c4366c
+        *al=SSL_AD_HANDSHAKE_FAILURE;
c4366c
+        return 0;
c4366c
+        }
c4366c
+    
c4366c
+    if(memcmp(d, s->s3->previous_client_finished,
c4366c
+	      s->s3->previous_client_finished_len))
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
c4366c
+        *al=SSL_AD_HANDSHAKE_FAILURE;
c4366c
+        return 0;
c4366c
+        }
c4366c
+#ifdef OPENSSL_RI_DEBUG
c4366c
+    fprintf(stderr, "%s RI extension received by server\n",
c4366c
+				ilen ? "Non-empty" : "Empty");
c4366c
+#endif
c4366c
+
c4366c
+    s->s3->send_connection_binding=1;
c4366c
+
c4366c
+    return 1;
c4366c
+    }
c4366c
+
c4366c
+/* Add the server's renegotiation binding */
c4366c
+int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
c4366c
+					int maxlen)
c4366c
+    {
c4366c
+    if(p)
c4366c
+        {
c4366c
+        if((s->s3->previous_client_finished_len +
c4366c
+            s->s3->previous_server_finished_len + 1) > maxlen)
c4366c
+            {
c4366c
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
c4366c
+            return 0;
c4366c
+            }
c4366c
+        
c4366c
+        /* Length byte */
c4366c
+        *p = s->s3->previous_client_finished_len + s->s3->previous_server_finished_len;
c4366c
+        p++;
c4366c
+
c4366c
+        memcpy(p, s->s3->previous_client_finished,
c4366c
+	       s->s3->previous_client_finished_len);
c4366c
+        p += s->s3->previous_client_finished_len;
c4366c
+
c4366c
+        memcpy(p, s->s3->previous_server_finished,
c4366c
+	       s->s3->previous_server_finished_len);
c4366c
+#ifdef OPENSSL_RI_DEBUG
c4366c
+    fprintf(stderr, "%s RI extension sent by server\n",
c4366c
+    		s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
c4366c
+#endif
c4366c
+        }
c4366c
+    
c4366c
+    *len=s->s3->previous_client_finished_len
c4366c
+	+ s->s3->previous_server_finished_len + 1;
c4366c
+    
c4366c
+    return 1;
c4366c
+    }
c4366c
+
c4366c
+/* Parse the server's renegotiation binding and abort if it's not
c4366c
+   right */
c4366c
+int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
c4366c
+					  int *al)
c4366c
+    {
c4366c
+    int expected_len=s->s3->previous_client_finished_len
c4366c
+	+ s->s3->previous_server_finished_len;
c4366c
+    int ilen;
c4366c
+
c4366c
+    /* Check for logic errors */
c4366c
+    OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
c4366c
+    OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);
c4366c
+    
c4366c
+    /* Parse the length byte */
c4366c
+    if(len < 1)
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
c4366c
+        *al=SSL_AD_ILLEGAL_PARAMETER;
c4366c
+        return 0;
c4366c
+        }
c4366c
+    ilen = *d;
c4366c
+    d++;
c4366c
+
c4366c
+    /* Consistency check */
c4366c
+    if(ilen+1 != len)
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
c4366c
+        *al=SSL_AD_ILLEGAL_PARAMETER;
c4366c
+        return 0;
c4366c
+        }
c4366c
+    
c4366c
+    /* Check that the extension matches */
c4366c
+    if(ilen != expected_len)
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
c4366c
+        *al=SSL_AD_HANDSHAKE_FAILURE;
c4366c
+        return 0;
c4366c
+        }
c4366c
+
c4366c
+    if(memcmp(d, s->s3->previous_client_finished,
c4366c
+	      s->s3->previous_client_finished_len))
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
c4366c
+        *al=SSL_AD_HANDSHAKE_FAILURE;
c4366c
+        return 0;
c4366c
+        }
c4366c
+    d += s->s3->previous_client_finished_len;
c4366c
+
c4366c
+    if(memcmp(d, s->s3->previous_server_finished,
c4366c
+	      s->s3->previous_server_finished_len))
c4366c
+        {
c4366c
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
c4366c
+        *al=SSL_AD_ILLEGAL_PARAMETER;
c4366c
+        return 0;
c4366c
+        }
c4366c
+#ifdef OPENSSL_RI_DEBUG
c4366c
+    fprintf(stderr, "%s RI extension received by client\n",
c4366c
+				ilen ? "Non-empty" : "Empty");
c4366c
+#endif
c4366c
+    s->s3->send_connection_binding=1;
c4366c
+
c4366c
+    return 1;
c4366c
+    }