Use minimum and maximum protocol version instead of version fixed methods
authorKurt Roeckx <kurt@roeckx.be>
Tue, 2 Feb 2016 22:58:49 +0000 (23:58 +0100)
committerKurt Roeckx <kurt@roeckx.be>
Wed, 9 Mar 2016 18:38:56 +0000 (19:38 +0100)
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
MR: #1824

apps/ciphers.c
apps/s_client.c
apps/s_server.c
apps/s_time.c
test/ssltest.c

index 3e1ed951a2877c7ddac0849d3fb1e9f23d417b23..924c0153b39dc3d9c9d22a9ad895b0411c3df931 100644 (file)
@@ -126,6 +126,7 @@ int ciphers_main(int argc, char **argv)
     char *ciphers = NULL, *prog;
     char buf[512];
     OPTION_CHOICE o;
+    int min_version = 0, max_version = 0;
 
     prog = opt_init(argc, argv, ciphers_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -154,24 +155,20 @@ int ciphers_main(int argc, char **argv)
 #endif
             break;
         case OPT_SSL3:
-#ifndef OPENSSL_NO_SSL3
-            meth = SSLv3_client_method();
-#endif
+            min_version = SSL3_VERSION;
+            max_version = SSL3_VERSION;
             break;
         case OPT_TLS1:
-#ifndef OPENSSL_NO_TLS1
-            meth = TLSv1_client_method();
-#endif
+            min_version = TLS1_VERSION;
+            max_version = TLS1_VERSION;
             break;
         case OPT_TLS1_1:
-#ifndef OPENSSL_NO_TLS1_1
-            meth = TLSv1_1_client_method();
-#endif
+            min_version = TLS1_1_VERSION;
+            max_version = TLS1_1_VERSION;
             break;
         case OPT_TLS1_2:
-#ifndef OPENSSL_NO_TLS1_2
-            meth = TLSv1_2_client_method();
-#endif
+            min_version = TLS1_2_VERSION;
+            max_version = TLS1_2_VERSION;
             break;
         case OPT_PSK:
 #ifndef OPENSSL_NO_PSK
@@ -191,6 +188,11 @@ int ciphers_main(int argc, char **argv)
     ctx = SSL_CTX_new(meth);
     if (ctx == NULL)
         goto err;
+    if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
+        goto err;
+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+        goto err;
+
 #ifndef OPENSSL_NO_PSK
     if (psk)
         SSL_CTX_set_psk_client_callback(ctx, dummy_psk);
index c338b0c5250a5b07f43383f1e3c0c6d5927e8cea..38d7c32a020985a64ee41818dc66d79d81ad2fc5 100644 (file)
@@ -928,6 +928,7 @@ int s_client_main(int argc, char **argv)
     char *ctlog_file = NULL;
     ct_validation_cb ct_validation = NULL;
 #endif
+    int min_version = 0, max_version = 0;
 
     FD_ZERO(&readfds);
     FD_ZERO(&writefds);
@@ -1199,25 +1200,30 @@ int s_client_main(int argc, char **argv)
 #ifndef OPENSSL_NO_SRP
         case OPT_SRPUSER:
             srp_arg.srplogin = opt_arg();
-            meth = TLSv1_client_method();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
             break;
         case OPT_SRPPASS:
             srppass = opt_arg();
-            meth = TLSv1_client_method();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
             break;
         case OPT_SRP_STRENGTH:
             srp_arg.strength = atoi(opt_arg());
             BIO_printf(bio_err, "SRP minimal length for N is %d\n",
                        srp_arg.strength);
-            meth = TLSv1_client_method();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
             break;
         case OPT_SRP_LATEUSER:
             srp_lateuser = 1;
-            meth = TLSv1_client_method();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
             break;
         case OPT_SRP_MOREGROUPS:
             srp_arg.amp = 1;
-            meth = TLSv1_client_method();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
             break;
 #else
         case OPT_SRPUSER:
@@ -1231,24 +1237,20 @@ int s_client_main(int argc, char **argv)
             ssl_config = opt_arg();
             break;
         case OPT_SSL3:
-#ifndef OPENSSL_NO_SSL3
-            meth = SSLv3_client_method();
-#endif
+            min_version = SSL3_VERSION;
+            max_version = SSL3_VERSION;
             break;
         case OPT_TLS1_2:
-#ifndef OPENSSL_NO_TLS1_2
-            meth = TLSv1_2_client_method();
-#endif
+            min_version = TLS1_2_VERSION;
+            max_version = TLS1_2_VERSION;
             break;
         case OPT_TLS1_1:
-#ifndef OPENSSL_NO_TLS1_1
-            meth = TLSv1_1_client_method();
-#endif
+            min_version = TLS1_1_VERSION;
+            max_version = TLS1_1_VERSION;
             break;
         case OPT_TLS1:
-#ifndef OPENSSL_NO_TLS1
-            meth = TLSv1_client_method();
-#endif
+            min_version = TLS1_VERSION;
+            max_version = TLS1_VERSION;
             break;
         case OPT_DTLS:
 #ifndef OPENSSL_NO_DTLS
@@ -1258,13 +1260,17 @@ int s_client_main(int argc, char **argv)
             break;
         case OPT_DTLS1:
 #ifndef OPENSSL_NO_DTLS1
-            meth = DTLSv1_client_method();
+            meth = DTLS_client_method();
+            min_version = DTLS1_VERSION;
+            max_version = DTLS1_VERSION;
             socket_type = SOCK_DGRAM;
 #endif
             break;
         case OPT_DTLS1_2:
 #ifndef OPENSSL_NO_DTLS1_2
-            meth = DTLSv1_2_client_method();
+            meth = DTLS_client_method();
+            min_version = DTLS1_2_VERSION;
+            max_version = DTLS1_2_VERSION;
             socket_type = SOCK_DGRAM;
 #endif
             break;
@@ -1566,6 +1572,11 @@ int s_client_main(int argc, char **argv)
         }
     }
 
+    if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
+        goto end;
+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+        goto end;
+
     if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) {
         BIO_printf(bio_err, "Error setting verify params\n");
         ERR_print_errors(bio_err);
index af85dd7e83578ee01c02e5b74b752f0dff7caf25..e77f2f4fa790b9f02a639b0cb4b79356a05c3f90 100644 (file)
@@ -1066,6 +1066,7 @@ int s_server_main(int argc, char *argv[])
     char *srpuserseed = NULL;
     char *srp_verifier_file = NULL;
 #endif
+    int min_version = 0, max_version = 0;
 
     local_argc = argc;
     local_argv = argv;
@@ -1389,13 +1390,15 @@ int s_server_main(int argc, char *argv[])
         case OPT_SRPVFILE:
 #ifndef OPENSSL_NO_SRP
             srp_verifier_file = opt_arg();
-            meth = TLSv1_server_method();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
 #endif
             break;
         case OPT_SRPUSERSEED:
 #ifndef OPENSSL_NO_SRP
             srpuserseed = opt_arg();
-            meth = TLSv1_server_method();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
 #endif
             break;
         case OPT_REV:
@@ -1414,24 +1417,20 @@ int s_server_main(int argc, char *argv[])
             ssl_config = opt_arg();
             break;
         case OPT_SSL3:
-#ifndef OPENSSL_NO_SSL3
-            meth = SSLv3_server_method();
-#endif
+            min_version = SSL3_VERSION;
+            max_version = SSL3_VERSION;
             break;
         case OPT_TLS1_2:
-#ifndef OPENSSL_NO_TLS1_2
-            meth = TLSv1_2_server_method();
-#endif
+            min_version = TLS1_2_VERSION;
+            max_version = TLS1_2_VERSION;
             break;
         case OPT_TLS1_1:
-#ifndef OPENSSL_NO_TLS1_1
-            meth = TLSv1_1_server_method();
-#endif
+            min_version = TLS1_1_VERSION;
+            max_version = TLS1_1_VERSION;
             break;
         case OPT_TLS1:
-#ifndef OPENSSL_NO_TLS1
-            meth = TLSv1_server_method();
-#endif
+            min_version = TLS1_VERSION;
+            max_version = TLS1_VERSION;
             break;
         case OPT_DTLS:
 #ifndef OPENSSL_NO_DTLS
@@ -1440,14 +1439,18 @@ int s_server_main(int argc, char *argv[])
 #endif
             break;
         case OPT_DTLS1:
-#ifndef OPENSSL_NO_DTLS1
-            meth = DTLSv1_server_method();
+#ifndef OPENSSL_NO_DTLS
+            meth = DTLS_server_method();
+            min_version = DTLS1_VERSION;
+            max_version = DTLS1_VERSION;
             socket_type = SOCK_DGRAM;
 #endif
             break;
         case OPT_DTLS1_2:
-#ifndef OPENSSL_NO_DTLS1_2
-            meth = DTLSv1_2_server_method();
+#ifndef OPENSSL_NO_DTLS
+            meth = DTLS_server_method();
+            min_version = DTLS1_2_VERSION;
+            max_version = DTLS1_2_VERSION;
             socket_type = SOCK_DGRAM;
 #endif
             break;
@@ -1728,6 +1731,10 @@ int s_server_main(int argc, char *argv[])
         goto end;
         }
     }
+    if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
+        goto end;
+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+        goto end;
 
     if (session_id_prefix) {
         if (strlen(session_id_prefix) >= 32)
index cc9a9797556e3b7d126defaace44701401c740db..f68002a224091841837b9af3b086747ebb282470 100644 (file)
@@ -132,7 +132,7 @@ OPTIONS s_time_options[] = {
     {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"},
     {"verify", OPT_VERIFY, 'p',
      "Turn on peer certificate verification, set depth"},
-    {"time", OPT_TIME, 'p', "Sf seconds to collect data, default" SECONDSSTR},
+    {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR},
     {"www", OPT_WWW, 's', "Fetch specified page from the site"},
 #ifndef OPENSSL_NO_SSL3
     {"ssl3", OPT_SSL3, '-', "Just use SSLv3"},
@@ -162,6 +162,7 @@ int s_time_main(int argc, char **argv)
         0, ver;
     long bytes_read = 0, finishtime = 0;
     OPTION_CHOICE o;
+    int max_version = 0;
 
     meth = TLS_client_method();
     verify_depth = 0;
@@ -230,9 +231,7 @@ int s_time_main(int argc, char **argv)
             }
             break;
         case OPT_SSL3:
-#ifndef OPENSSL_NO_SSL3
-            meth = SSLv3_client_method();
-#endif
+            max_version = SSL3_VERSION;
             break;
         }
     }
@@ -251,6 +250,8 @@ int s_time_main(int argc, char **argv)
         goto end;
 
     SSL_CTX_set_quiet_shutdown(ctx, 1);
+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+        goto end;
 
     if (st_bugs)
         SSL_CTX_set_options(ctx, SSL_OP_ALL);
index e5f86155c2a7ee55d1d6e130fae4e5f04c887af1..972d76bef0e4a92501c3507dd4185894dbbbcd0d 100644 (file)
@@ -830,8 +830,8 @@ static void sv_usage(void)
     fprintf(stderr, " -psk arg      - PSK in hex (without 0x)\n");
 #endif
 #ifndef OPENSSL_NO_SRP
-    fprintf(stderr, " -srpuser user  - SRP username to use\n");
-    fprintf(stderr, " -srppass arg   - password for 'user'\n");
+    fprintf(stderr, " -srpuser user - SRP username to use\n");
+    fprintf(stderr, " -srppass arg  - password for 'user'\n");
 #endif
 #ifndef OPENSSL_NO_SSL3
     fprintf(stderr, " -ssl3         - use SSLv3\n");
@@ -840,7 +840,7 @@ static void sv_usage(void)
     fprintf(stderr, " -tls1         - use TLSv1\n");
 #endif
 #ifndef OPENSSL_NO_DTLS
-    fprintf(stderr, " -dtls        - use DTLS\n");
+    fprintf(stderr, " -dtls         - use DTLS\n");
 #ifndef OPENSSL_NO_DTLS1
     fprintf(stderr, " -dtls1        - use DTLSv1\n");
 #endif
@@ -1056,6 +1056,7 @@ int main(int argc, char *argv[])
     int fips_mode = 0;
 #endif
     int no_protocol;
+    int min_version = 0, max_version = 0;
 
 #ifndef OPENSSL_NO_CT
     /*
@@ -1186,12 +1187,12 @@ int main(int argc, char *argv[])
                 goto bad;
             srp_server_arg.expected_user = srp_client_arg.srplogin =
                 *(++argv);
-            tls1 = 1;
+            min_version = TLS1_VERSION;
         } else if (strcmp(*argv, "-srppass") == 0) {
             if (--argc < 1)
                 goto bad;
             srp_server_arg.pass = srp_client_arg.srppassin = *(++argv);
-            tls1 = 1;
+            min_version = TLS1_VERSION;
         }
 #endif
         else if (strcmp(*argv, "-tls1") == 0) {
@@ -1495,37 +1496,27 @@ int main(int argc, char *argv[])
     }
 #endif
 
-    /*
-     * At this point, ssl3/tls1 is only set if the protocol is available.
-     * (Otherwise we exit early.) However the compiler doesn't know this, so
-     * we ifdef.
-     */
-#ifndef OPENSSL_NO_DTLS
-#ifndef OPENSSL_NO_DTLS1
-    if (dtls1)
-        meth = DTLSv1_method();
-    else
-#endif
-#ifndef OPENSSL_NO_DTLS1_2
-    if (dtls12)
-        meth = DTLSv1_2_method();
-    else
+#ifndef OPENSSL_NO_TLS
+    meth = TLS_method();
+    if (ssl3) {
+        min_version = SSL3_VERSION;
+        max_version = SSL3_VERSION;
+    } else if (tls1) {
+        min_version = TLS1_VERSION;
+        max_version = TLS1_VERSION;
+    }
 #endif
-    if (dtls)
+#ifndef OPENSSL_NO_DTLS
+    if (dtls || dtls1 || dtls12)
         meth = DTLS_method();
-    else
-#endif
-#ifndef OPENSSL_NO_SSL3
-    if (ssl3)
-        meth = SSLv3_method();
-    else
-#endif
-#ifndef OPENSSL_NO_TLS1
-    if (tls1)
-        meth = TLSv1_method();
-    else
+    if (dtls1) {
+        min_version = DTLS1_VERSION;
+        max_version = DTLS1_VERSION;
+    } else if (dtls12) {
+        min_version = DTLS1_2_VERSION;
+        max_version = DTLS1_2_VERSION;
+    }
 #endif
-        meth = TLS_method();
 
     c_ctx = SSL_CTX_new(meth);
     s_ctx = SSL_CTX_new(meth);
@@ -1543,6 +1534,15 @@ int main(int argc, char *argv[])
     SSL_CTX_set_security_level(s_ctx, 0);
     SSL_CTX_set_security_level(s_ctx2, 0);
 
+    if (SSL_CTX_set_min_proto_version(c_ctx, min_version) == 0)
+        goto end;
+    if (SSL_CTX_set_max_proto_version(c_ctx, max_version) == 0)
+        goto end;
+    if (SSL_CTX_set_min_proto_version(s_ctx, min_version) == 0)
+        goto end;
+    if (SSL_CTX_set_max_proto_version(s_ctx, max_version) == 0)
+        goto end;
+
     if (cipher != NULL) {
         if (!SSL_CTX_set_cipher_list(c_ctx, cipher)
             || !SSL_CTX_set_cipher_list(s_ctx, cipher)