Commit f2ad3582 authored by Andy Polyakov's avatar Andy Polyakov
Browse files

s23_clnt.c: ensure interoperability by maitaining client "version capability"

vector contiguous.
PR: 2802
parent 09e4e4b9
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -289,6 +289,16 @@
     whose return value is often ignored. 
     [Steve Henson]

 Changes between 1.0.1a and 1.0.1b [xx XXX xxxx]

  *) In order to ensure interoperabilty SSL_OP_NO_protocolX does not
     disable just protocol X, but all protocols above X *if* there are
     protocols *below* X still enabled. In more practical terms it means
     that if application wants to disable TLS1.0 in favor of TLS1.1 and
     above, it's not sufficient to pass SSL_OP_NO_TLSv1, one has to pass
     SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2.
     [Andy Polyakov]

 Changes between 1.0.1 and 1.0.1a [19 Apr 2012]

  *) Check for potentially exploitable overflows in asn1_d2i_read_bio
+36 −17
Original line number Diff line number Diff line
@@ -282,32 +282,51 @@ static int ssl23_client_hello(SSL *s)
	SSL_COMP *comp;
#endif
	int ret;
	unsigned long mask, options = s->options;

	ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1;
	ssl2_compat = (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_2))
		{
	/*
	 * SSL_OP_NO_X disables all protocols above X *if* there are
	 * some protocols below X enabled. This is required in order
	 * to maintain "version capability" vector contiguous. So
	 * that if application wants to disable TLS1.0 in favour of
	 * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the
	 * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2.
	 */
	mask =	SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1
#if !defined(OPENSSL_NO_SSL3)
		|SSL_OP_NO_SSLv3
#endif
#if !defined(OPENSSL_NO_SSL2)
		|(ssl2_compat?SSL_OP_NO_SSLv2:0)
#endif
		;
#if !defined(OPENSSL_NO_TLS1_2_CLIENT)
	version = TLS1_2_VERSION;
		}
	else if (!(s->options & SSL_OP_NO_TLSv1_1))
		{

	if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask)
		version = TLS1_1_VERSION;
		}
	else if (!(s->options & SSL_OP_NO_TLSv1))
		{
#else
	version = TLS1_1_VERSION;
#endif
	mask &= ~SSL_OP_NO_TLSv1_1;
	if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask)
		version = TLS1_VERSION;
		}
	else if (!(s->options & SSL_OP_NO_SSLv3))
		{
	mask &= ~SSL_OP_NO_TLSv1;
#if !defined(OPENSSL_NO_SSL3)
	if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask)
		version = SSL3_VERSION;
		}
	else if (!(s->options & SSL_OP_NO_SSLv2))
		{
	mask &= ~SSL_OP_NO_SSLv3;
#endif
#if !defined(OPENSSL_NO_SSL2)
	if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask)
		version = SSL2_VERSION;
		}
#endif

#ifndef OPENSSL_NO_TLSEXT
	if (version != SSL2_VERSION)
		{