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

vector contiguous.
PR: 2802
This commit is contained in:
Andy Polyakov 2012-04-25 22:06:32 +00:00
parent 09e4e4b98e
commit f2ad35821c
2 changed files with 47 additions and 18 deletions

10
CHANGES
View File

@ -289,6 +289,16 @@
whose return value is often ignored. whose return value is often ignored.
[Steve Henson] [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] Changes between 1.0.1 and 1.0.1a [19 Apr 2012]
*) Check for potentially exploitable overflows in asn1_d2i_read_bio *) Check for potentially exploitable overflows in asn1_d2i_read_bio

View File

@ -282,32 +282,51 @@ static int ssl23_client_hello(SSL *s)
SSL_COMP *comp; SSL_COMP *comp;
#endif #endif
int ret; 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)) if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
ssl2_compat = 0; 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; 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; version = TLS1_1_VERSION;
} #else
else if (!(s->options & SSL_OP_NO_TLSv1)) version = TLS1_1_VERSION;
{ #endif
mask &= ~SSL_OP_NO_TLSv1_1;
if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask)
version = TLS1_VERSION; version = TLS1_VERSION;
} mask &= ~SSL_OP_NO_TLSv1;
else if (!(s->options & SSL_OP_NO_SSLv3)) #if !defined(OPENSSL_NO_SSL3)
{ if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask)
version = SSL3_VERSION; version = SSL3_VERSION;
} mask &= ~SSL_OP_NO_SSLv3;
else if (!(s->options & SSL_OP_NO_SSLv2)) #endif
{ #if !defined(OPENSSL_NO_SSL2)
if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask)
version = SSL2_VERSION; version = SSL2_VERSION;
} #endif
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
if (version != SSL2_VERSION) if (version != SSL2_VERSION)
{ {