From 032924c4b4104654ff8659b4701e4ab25872a12e Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 25 Jul 2016 18:03:27 +0100 Subject: [PATCH] Make DTLS1_BAD_VER work with DTLS_client_method() DTLSv1_client_method() is deprecated, but it was the only way to obtain DTLS1_BAD_VER support. The SSL_OP_CISCO_ANYCONNECT hack doesn't work with DTLS_client_method(), and it's relatively non-trivial to make it work without expanding the hack into lots of places. So deprecate SSL_OP_CISCO_ANYCONNECT with DTLSv1_client_method(), and make it work with SSL_CTX_set_{min,max}_proto_version(DTLS1_BAD_VER) instead. Reviewed-by: Rich Salz Reviewed-by: Matt Caswell --- include/openssl/ssl.h | 7 +++++-- ssl/d1_lib.c | 9 ++++++--- ssl/methods.c | 5 +++++ ssl/record/rec_layer_d1.c | 3 ++- ssl/ssl_locl.h | 1 + ssl/statem/statem_lib.c | 4 +++- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 2aca2f94d5..e58ad30099 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -306,8 +306,11 @@ typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type, # define SSL_OP_COOKIE_EXCHANGE 0x00002000U /* Don't use RFC4507 ticket extension */ # define SSL_OP_NO_TICKET 0x00004000U -/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client) */ -# define SSL_OP_CISCO_ANYCONNECT 0x00008000U +# ifndef OPENSSL_NO_DTLS1_METHOD +/* Use Cisco's "speshul" version of DTLS_BAD_VER + * (only with deprecated DTLSv1_client_method()) */ +# define SSL_OP_CISCO_ANYCONNECT 0x00008000U +# endif /* As server, disallow session resumption on renegotiation */ # define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000U diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 0a985551b8..08a503786f 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -179,10 +179,13 @@ void dtls1_clear(SSL *s) } ssl3_clear(s); - if (s->options & SSL_OP_CISCO_ANYCONNECT) - s->client_version = s->version = DTLS1_BAD_VER; - else if (s->method->version == DTLS_ANY_VERSION) + + if (s->method->version == DTLS_ANY_VERSION) s->version = DTLS_MAX_VERSION; +#ifndef OPENSSL_NO_DTLS1_METHOD + else if (s->options & SSL_OP_CISCO_ANYCONNECT) + s->client_version = s->version = DTLS1_BAD_VER; +#endif else s->version = s->method->version; } diff --git a/ssl/methods.c b/ssl/methods.c index aeed8c72bd..7d27f9d8ff 100644 --- a/ssl/methods.c +++ b/ssl/methods.c @@ -191,6 +191,11 @@ IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1, ssl_undefined_function, ossl_statem_connect, DTLSv1_enc_data) +IMPLEMENT_dtls1_meth_func(DTLS1_BAD_VER, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1, + dtls_bad_ver_client_method, + ssl_undefined_function, + ossl_statem_connect, + DTLSv1_enc_data) #endif #ifndef OPENSSL_NO_DTLS1_2_METHOD diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index cca5721efa..7ddadfa2bd 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -980,7 +980,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, * haven't decided which version to use yet send back using version 1.0 * header: otherwise some clients will ignore it. */ - if (s->method->version == DTLS_ANY_VERSION) { + if (s->method->version == DTLS_ANY_VERSION && + s->max_proto_version != DTLS1_BAD_VER) { *(p++) = DTLS1_VERSION >> 8; *(p++) = DTLS1_VERSION & 0xff; } else { diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 550c4d5ef8..ef05f70824 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1655,6 +1655,7 @@ __owur const SSL_METHOD *tlsv1_2_client_method(void); __owur const SSL_METHOD *dtlsv1_method(void); __owur const SSL_METHOD *dtlsv1_server_method(void); __owur const SSL_METHOD *dtlsv1_client_method(void); +__owur const SSL_METHOD *dtls_bad_ver_client_method(void); __owur const SSL_METHOD *dtlsv1_2_method(void); __owur const SSL_METHOD *dtlsv1_2_server_method(void); __owur const SSL_METHOD *dtlsv1_2_client_method(void); diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index df07800e65..ae986f5c63 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -681,8 +681,10 @@ static const version_info dtls_version_table[] = { #endif #ifndef OPENSSL_NO_DTLS1 { DTLS1_VERSION, dtlsv1_client_method, dtlsv1_server_method }, + { DTLS1_BAD_VER, dtls_bad_ver_client_method, NULL }, #else { DTLS1_VERSION, NULL, NULL }, + { DTLS1_BAD_VER, NULL, NULL }, #endif { 0, NULL, NULL }, }; @@ -847,7 +849,7 @@ int ssl_set_version_bound(int method_version, int version, int *bound) case DTLS_ANY_VERSION: if (DTLS_VERSION_GT(version, DTLS_MAX_VERSION) || - DTLS_VERSION_LT(version, DTLS1_VERSION)) + DTLS_VERSION_LT(version, DTLS1_BAD_VER)) return 0; break; } -- 2.25.1