Make DTLS1_BAD_VER work with DTLS_client_method()
authorDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 25 Jul 2016 17:03:27 +0000 (18:03 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 4 Aug 2016 19:56:24 +0000 (20:56 +0100)
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 <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
include/openssl/ssl.h
ssl/d1_lib.c
ssl/methods.c
ssl/record/rec_layer_d1.c
ssl/ssl_locl.h
ssl/statem/statem_lib.c

index 2aca2f9..e58ad30 100644 (file)
@@ -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
index 0a98555..08a5037 100644 (file)
@@ -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;
 }
index aeed8c7..7d27f9d 100644 (file)
@@ -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
index cca5721..7ddadfa 100644 (file)
@@ -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 {
index 550c4d5..ef05f70 100644 (file)
@@ -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);
index df07800..ae986f5 100644 (file)
@@ -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;
     }