| Index: openssl/ssl/s23_clnt.c | 
| =================================================================== | 
| --- openssl/ssl/s23_clnt.c	(revision 105093) | 
| +++ openssl/ssl/s23_clnt.c	(working copy) | 
| @@ -55,6 +55,59 @@ | 
| * copied and put under another distribution licence | 
| * [including the GNU Public Licence.] | 
| */ | 
| +/* ==================================================================== | 
| + * Copyright (c) 1998-2006 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 "ssl_locl.h" | 
| @@ -63,10 +116,10 @@ | 
| #include <openssl/objects.h> | 
| #include <openssl/evp.h> | 
|  | 
| -static SSL_METHOD *ssl23_get_client_method(int ver); | 
| +static const SSL_METHOD *ssl23_get_client_method(int ver); | 
| static int ssl23_client_hello(SSL *s); | 
| static int ssl23_get_server_hello(SSL *s); | 
| -static SSL_METHOD *ssl23_get_client_method(int ver) | 
| +static const SSL_METHOD *ssl23_get_client_method(int ver) | 
| { | 
| #ifndef OPENSSL_NO_SSL2 | 
| if (ver == SSL2_VERSION) | 
| @@ -197,6 +250,20 @@ | 
| return(ret); | 
| } | 
|  | 
| +static int ssl23_no_ssl2_ciphers(SSL *s) | 
| +	{ | 
| +	SSL_CIPHER *cipher; | 
| +	STACK_OF(SSL_CIPHER) *ciphers; | 
| +	int i; | 
| +	ciphers = SSL_get_ciphers(s); | 
| +	for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) | 
| +		{ | 
| +		cipher = sk_SSL_CIPHER_value(ciphers, i); | 
| +		if (cipher->algorithm_ssl == SSL_SSLV2) | 
| +			return 0; | 
| +		} | 
| +	return 1; | 
| +	} | 
|  | 
| static int ssl23_client_hello(SSL *s) | 
| { | 
| @@ -214,6 +281,9 @@ | 
|  | 
| ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1; | 
|  | 
| +	if (ssl2_compat && ssl23_no_ssl2_ciphers(s)) | 
| +		ssl2_compat = 0; | 
| + | 
| if (!(s->options & SSL_OP_NO_TLSv1)) | 
| { | 
| version = TLS1_VERSION; | 
| @@ -226,7 +296,7 @@ | 
| { | 
| version = SSL2_VERSION; | 
| } | 
| -#ifndef OPENSSL_NO_TLSEXT | 
| +#ifndef OPENSSL_NO_TLSEXT | 
| if (version != SSL2_VERSION) | 
| { | 
| /* have to disable SSL 2.0 compatibility if we need TLS extensions */ | 
| @@ -235,6 +305,10 @@ | 
| ssl2_compat = 0; | 
| if (s->tlsext_status_type != -1) | 
| ssl2_compat = 0; | 
| +#ifdef TLSEXT_TYPE_opaque_prf_input | 
| +		if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL) | 
| +			ssl2_compat = 0; | 
| +#endif | 
| } | 
| #endif | 
|  | 
| @@ -260,14 +334,6 @@ | 
| version_major = TLS1_VERSION_MAJOR; | 
| version_minor = TLS1_VERSION_MINOR; | 
| } | 
| -#ifdef OPENSSL_FIPS | 
| -		else if(FIPS_mode()) | 
| -			{ | 
| -			SSLerr(SSL_F_SSL23_CLIENT_HELLO, | 
| -					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); | 
| -			return -1; | 
| -			} | 
| -#endif | 
| else if (version == SSL3_VERSION) | 
| { | 
| version_major = SSL3_VERSION_MAJOR; | 
| @@ -321,6 +387,10 @@ | 
| ch_len=SSL2_MAX_CHALLENGE_LENGTH; | 
|  | 
| /* write out sslv2 challenge */ | 
| +			/* Note that ch_len must be <= SSL3_RANDOM_SIZE (32), | 
| +			   because it is one of SSL2_MAX_CHALLENGE_LENGTH (32) | 
| +			   or SSL2_MAX_CHALLENGE_LENGTH (16), but leave the | 
| +			   check in for futurproofing */ | 
| if (SSL3_RANDOM_SIZE < ch_len) | 
| i=SSL3_RANDOM_SIZE; | 
| else | 
| @@ -369,11 +439,13 @@ | 
| } | 
| s2n(i,p); | 
| p+=i; | 
| + | 
| +			/* COMPRESSION */ | 
| #ifdef OPENSSL_NO_COMP | 
| *(p++)=1; | 
| #else | 
| -			/* COMPRESSION */ | 
| -			if (s->ctx->comp_methods == NULL) | 
| +			if ((s->options & SSL_OP_NO_COMPRESSION) | 
| +						|| !s->ctx->comp_methods) | 
| j=0; | 
| else | 
| j=sk_SSL_COMP_num(s->ctx->comp_methods); | 
| @@ -385,7 +457,14 @@ | 
| } | 
| #endif | 
| *(p++)=0; /* Add the NULL method */ | 
| + | 
| #ifndef OPENSSL_NO_TLSEXT | 
| +			/* TLS extensions*/ | 
| +			if (ssl_prepare_clienthello_tlsext(s) <= 0) | 
| +				{ | 
| +				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); | 
| +				return -1; | 
| +				} | 
| if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) | 
| { | 
| SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); | 
| @@ -394,7 +473,6 @@ | 
| #endif | 
|  | 
| l = p-d; | 
| -			*p = 42; | 
|  | 
| /* fill in 4-byte handshake header */ | 
| d=&(buf[5]); | 
| @@ -489,6 +567,10 @@ | 
| ch_len=SSL2_MAX_CHALLENGE_LENGTH; | 
|  | 
| /* write out sslv2 challenge */ | 
| +		/* Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because | 
| +		   it is one of SSL2_MAX_CHALLENGE_LENGTH (32) or | 
| +		   SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for | 
| +		   futurproofing */ | 
| i=(SSL3_RANDOM_SIZE < ch_len) | 
| ?SSL3_RANDOM_SIZE:ch_len; | 
| s->s2->challenge_length=i; | 
| @@ -509,7 +591,7 @@ | 
| /* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */ | 
| s->s2->ssl2_rollback=1; | 
|  | 
| -		/* setup the 5 bytes we have read so we get them from | 
| +		/* setup the 7 bytes we have read so we get them from | 
| * the sslv2 buffer */ | 
| s->rstate=SSL_ST_READ_HEADER; | 
| s->packet_length=n; | 
| @@ -525,39 +607,16 @@ | 
| s->handshake_func=s->method->ssl_connect; | 
| #endif | 
| } | 
| -	else if ((p[0] == SSL3_RT_HANDSHAKE) && | 
| -		 (p[1] == SSL3_VERSION_MAJOR) && | 
| -		 ((p[2] == SSL3_VERSION_MINOR) || | 
| -		  (p[2] == TLS1_VERSION_MINOR)) && | 
| -		 (p[5] == SSL3_MT_SERVER_HELLO)) | 
| +	else if (p[1] == SSL3_VERSION_MAJOR && | 
| +	         (p[2] == SSL3_VERSION_MINOR || p[2] == TLS1_VERSION_MINOR) && | 
| +	         ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || | 
| +	          (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) | 
| { | 
| -		/* we have sslv3 or tls1 */ | 
| +		/* we have sslv3 or tls1 (server hello or alert) */ | 
|  | 
| -		if (!ssl_init_wbio_buffer(s,1)) goto err; | 
| - | 
| -		/* we are in this state */ | 
| -		s->state=SSL3_ST_CR_SRVR_HELLO_A; | 
| - | 
| -		/* put the 5 bytes we have read into the input buffer | 
| -		 * for SSLv3 */ | 
| -		s->rstate=SSL_ST_READ_HEADER; | 
| -		s->packet_length=n; | 
| -		s->packet= &(s->s3->rbuf.buf[0]); | 
| -		memcpy(s->packet,buf,n); | 
| -		s->s3->rbuf.left=n; | 
| -		s->s3->rbuf.offset=0; | 
| - | 
| if ((p[2] == SSL3_VERSION_MINOR) && | 
| !(s->options & SSL_OP_NO_SSLv3)) | 
| { | 
| -#ifdef OPENSSL_FIPS | 
| -			if(FIPS_mode()) | 
| -				{ | 
| -				SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, | 
| -					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); | 
| -				goto err; | 
| -				} | 
| -#endif | 
| s->version=SSL3_VERSION; | 
| s->method=SSLv3_client_method(); | 
| } | 
| @@ -572,35 +631,52 @@ | 
| SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); | 
| goto err; | 
| } | 
| + | 
| +		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) | 
| +			{ | 
| +			/* fatal alert */ | 
| + | 
| +			void (*cb)(const SSL *ssl,int type,int val)=NULL; | 
| +			int j; | 
| + | 
| +			if (s->info_callback != NULL) | 
| +				cb=s->info_callback; | 
| +			else if (s->ctx->info_callback != NULL) | 
| +				cb=s->ctx->info_callback; | 
| + | 
| +			i=p[5]; | 
| +			if (cb != NULL) | 
| +				{ | 
| +				j=(i<<8)|p[6]; | 
| +				cb(s,SSL_CB_READ_ALERT,j); | 
| +				} | 
|  | 
| -		s->handshake_func=s->method->ssl_connect; | 
| -		} | 
| -	else if ((p[0] == SSL3_RT_ALERT) && | 
| -		 (p[1] == SSL3_VERSION_MAJOR) && | 
| -		 ((p[2] == SSL3_VERSION_MINOR) || | 
| -		  (p[2] == TLS1_VERSION_MINOR)) && | 
| -		 (p[3] == 0) && | 
| -		 (p[4] == 2)) | 
| -		{ | 
| -		void (*cb)(const SSL *ssl,int type,int val)=NULL; | 
| -		int j; | 
| +			if (s->msg_callback) | 
| +				s->msg_callback(0, s->version, SSL3_RT_ALERT, p+5, 2, s, s->msg_callback_arg); | 
|  | 
| -		/* An alert */ | 
| -		if (s->info_callback != NULL) | 
| -			cb=s->info_callback; | 
| -		else if (s->ctx->info_callback != NULL) | 
| -			cb=s->ctx->info_callback; | 
| - | 
| -		i=p[5]; | 
| -		if (cb != NULL) | 
| -			{ | 
| -			j=(i<<8)|p[6]; | 
| -			cb(s,SSL_CB_READ_ALERT,j); | 
| +			s->rwstate=SSL_NOTHING; | 
| +			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]); | 
| +			goto err; | 
| } | 
|  | 
| -		s->rwstate=SSL_NOTHING; | 
| -		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]); | 
| -		goto err; | 
| +		if (!ssl_init_wbio_buffer(s,1)) goto err; | 
| + | 
| +		/* we are in this state */ | 
| +		s->state=SSL3_ST_CR_SRVR_HELLO_A; | 
| + | 
| +		/* put the 7 bytes we have read into the input buffer | 
| +		 * for SSLv3 */ | 
| +		s->rstate=SSL_ST_READ_HEADER; | 
| +		s->packet_length=n; | 
| +		if (s->s3->rbuf.buf == NULL) | 
| +			if (!ssl3_setup_read_buffer(s)) | 
| +				goto err; | 
| +		s->packet= &(s->s3->rbuf.buf[0]); | 
| +		memcpy(s->packet,buf,n); | 
| +		s->s3->rbuf.left=n; | 
| +		s->s3->rbuf.offset=0; | 
| + | 
| +		s->handshake_func=s->method->ssl_connect; | 
| } | 
| else | 
| { | 
| @@ -611,6 +687,13 @@ | 
|  | 
| /* Since, if we are sending a ssl23 client hello, we are not | 
| * reusing a session-id */ | 
| +        if (!s->session_creation_enabled) | 
| +		{ | 
| +		if (!(s->client_version == SSL2_VERSION)) | 
| +			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); | 
| +		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); | 
| +		goto err; | 
| +		} | 
| if (!ssl_get_new_session(s,0)) | 
| goto err; | 
|  | 
| @@ -618,4 +701,3 @@ | 
| err: | 
| return(-1); | 
| } | 
| - | 
|  |