]> granicus.if.org Git - curl/commitdiff
SSL: protocol version can be specified more precisely
authorGergely Nagy <ngg@tresorit.com>
Thu, 19 Sep 2013 13:17:13 +0000 (15:17 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 15 Oct 2013 18:26:47 +0000 (20:26 +0200)
CURL_SSLVERSION_TLSv1_0, CURL_SSLVERSION_TLSv1_1,
CURL_SSLVERSION_TLSv1_2 enum values are added to force exact TLS version
(CURL_SSLVERSION_TLSv1 means TLS 1.x).

axTLS:
axTLS only supports TLS 1.0 and 1.1 but it cannot be set that only one
of these should be used, so we don't allow the new enum values.

darwinssl:
Added support for the new enum values.

SChannel:
Added support for the new enum values.

CyaSSL:
Added support for the new enum values.
Bug: The original CURL_SSLVERSION_TLSv1 value enables only TLS 1.0 (it
did the same before this commit), because CyaSSL cannot be configured to
use TLS 1.0-1.2.

GSKit:
GSKit doesn't seem to support TLS 1.1 and TLS 1.2, so we do not allow
those values.
Bugfix: There was a typo that caused wrong SSL versions to be passed to
GSKit.

NSS:
TLS minor version cannot be set, so we don't allow the new enum values.

QsoSSL:
TLS minor version cannot be set, so we don't allow the new enum values.

OpenSSL:
Added support for the new enum values.
Bugfix: The original CURL_SSLVERSION_TLSv1 value enabled only TLS 1.0,
now it enables 1.0-1.2.

Command-line tool:
Added command line options for the new values.

14 files changed:
docs/libcurl/curl_easy_setopt.3
docs/libcurl/symbols-in-versions
include/curl/curl.h
lib/axtls.c
lib/curl_darwinssl.c
lib/curl_schannel.c
lib/cyassl.c
lib/gskit.c
lib/nss.c
lib/qssl.c
lib/ssluse.c
packages/OS400/curl.inc.in
src/tool_getparam.c
src/tool_setopt.c

index 6c928834ec33e8e6d6d1a4db477d4567c571472a..77fc550e1b3080a5aa72b7a63e4a1bbade7090d0 100644 (file)
@@ -2417,11 +2417,17 @@ The default action. This will attempt to figure out the remote SSL protocol
 version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled
 by default with 7.18.1).
 .IP CURL_SSLVERSION_TLSv1
-Force TLSv1
+Force TLSv1.x
 .IP CURL_SSLVERSION_SSLv2
 Force SSLv2
 .IP CURL_SSLVERSION_SSLv3
 Force SSLv3
+.IP CURL_SSLVERSION_TLSv1_0
+Force TLSv1.0
+.IP CURL_SSLVERSION_TLSv1_1
+Force TLSv1.1
+.IP CURL_SSLVERSION_TLSv1_2
+Force TLSv1.2
 .RE
 .IP CURLOPT_SSL_VERIFYPEER
 Pass a long as parameter. By default, curl assumes a value of 1.
index 7c362cde7df61d0f336204722cb298e9146096cb..35b08789cfb1e274c7879a10b0de594b3cdc64d2 100644 (file)
@@ -695,6 +695,9 @@ CURL_SSLVERSION_DEFAULT         7.9.2
 CURL_SSLVERSION_SSLv2           7.9.2
 CURL_SSLVERSION_SSLv3           7.9.2
 CURL_SSLVERSION_TLSv1           7.9.2
+CURL_SSLVERSION_TLSv1_0         7.33.0
+CURL_SSLVERSION_TLSv1_1         7.33.0
+CURL_SSLVERSION_TLSv1_2         7.33.0
 CURL_TIMECOND_IFMODSINCE        7.9.7
 CURL_TIMECOND_IFUNMODSINCE      7.9.7
 CURL_TIMECOND_LASTMOD           7.9.7
index 4e09cf72882fd51d9d1e0566b0b7ab4704c2fde9..e3c6bf279d90183c5d92ecb4d4779d967e5c503a 100644 (file)
@@ -1659,9 +1659,12 @@ enum CURL_NETRC_OPTION {
 
 enum {
   CURL_SSLVERSION_DEFAULT,
-  CURL_SSLVERSION_TLSv1,
+  CURL_SSLVERSION_TLSv1, /* TLS 1.x */
   CURL_SSLVERSION_SSLv2,
   CURL_SSLVERSION_SSLv3,
+  CURL_SSLVERSION_TLSv1_0,
+  CURL_SSLVERSION_TLSv1_1,
+  CURL_SSLVERSION_TLSv1_2,
 
   CURL_SSLVERSION_LAST /* never use, keep last */
 };
index 44e6b9303c523c7e137460de0da05e64730d369a..8c92588f71489b7f31a3add8ed265b47381a9a30 100644 (file)
@@ -164,7 +164,8 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
   case CURL_SSLVERSION_TLSv1:
     break;
   default:
-    failf(data, "axTLS only supports TLSv1");
+    failf(data, "axTLS only supports TLS 1.0 and 1.1, "
+          "and it cannot be specified which one to use");
     return CURLE_SSL_CONNECT_ERROR;
   }
 
index fb404e9df0b34b1693361ef062bc243a7ef8593f..45a668bdd3abc19c26ad69917b464e085d60f102 100644 (file)
@@ -1056,6 +1056,18 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
         (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
         break;
+      case CURL_SSLVERSION_TLSv1_0:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+        break;
       case CURL_SSLVERSION_SSLv3:
         (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
@@ -1100,6 +1112,21 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
                                            kTLSProtocol12,
                                            true);
         break;
+      case CURL_SSLVERSION_TLSv1_0:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol1,
+                                           true);
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol11,
+                                           true);
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol12,
+                                           true);
+        break;
       case CURL_SSLVERSION_SSLv3:
         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
                                            kSSLProtocol3,
@@ -1130,10 +1157,17 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
                                          true);
       break;
     case CURL_SSLVERSION_TLSv1:
+    case CURL_SSLVERSION_TLSv1_0:
       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
                                          kTLSProtocol1,
                                          true);
       break;
+    case CURL_SSLVERSION_TLSv1_1:
+      failf(data, "Your version of the OS does not support TLSv1.1");
+      return CURLE_SSL_CONNECT_ERROR;
+    case CURL_SSLVERSION_TLSv1_2:
+      failf(data, "Your version of the OS does not support TLSv1.2");
+      return CURLE_SSL_CONNECT_ERROR;
     case CURL_SSLVERSION_SSLv2:
       err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
                                          kSSLProtocol2,
index 68139db586160af8129389740150b238d74ad0da..9a165278253c7621581858732c4952853787c228 100644 (file)
@@ -180,6 +180,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
                                               SP_PROT_TLS1_1_CLIENT |
                                               SP_PROT_TLS1_2_CLIENT;
         break;
+      case CURL_SSLVERSION_TLSv1_0:
+        schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
+        break;
       case CURL_SSLVERSION_SSLv3:
         schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
         break;
index 7c78464d8a1590d4639b45460c499bab9e23cf4b..ff11bdd1a17d7948c2099bf69ad64044a6e9f618 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -98,8 +98,19 @@ cyassl_connect_step1(struct connectdata *conn,
     req_method = SSLv23_client_method();
     break;
   case CURL_SSLVERSION_TLSv1:
+    infof(data, "CyaSSL cannot be configured to use TLS 1.0-1.2, "
+          "TLS 1.0 is used exclusively\n");
     req_method = TLSv1_client_method();
     break;
+  case CURL_SSLVERSION_TLSv1_0:
+    req_method = TLSv1_client_method();
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    req_method = TLSv1_1_client_method();
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    req_method = TLSv1_2_client_method();
+    break;
   case CURL_SSLVERSION_SSLv3:
     req_method = SSLv3_client_method();
     break;
index 5cda85b9b8949ac226bad8f6962d18912cbf39df..187c58d7a680c8d3f56855357a4804c7f5f0c259 100644 (file)
@@ -503,8 +503,17 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
     sni = (char *) NULL;
     break;
   case CURL_SSLVERSION_TLSv1:
+  case CURL_SSLVERSION_TLSv1_0:
     tlsv1enable = true;
     break;
+  case CURL_SSLVERSION_TLSv1_1:
+    failf(data, "GSKit doesn't support TLS 1.1!");
+    cc = CURLE_SSL_CONNECT_ERROR;
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    failf(data, "GSKit doesn't support TLS 1.2!");
+    cc = CURLE_SSL_CONNECT_ERROR;
+    break;
   default:              /* CURL_SSLVERSION_DEFAULT. */
     sslv3enable = true;
     tlsv1enable = true;
@@ -555,7 +564,7 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
                   GSK_PROTOCOL_SSLV3_OFF);
   if(cc == CURLE_OK)
     cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
-                  sslv3enable?  GSK_PROTOCOL_TLSV1_ON:
+                  tlsv1enable?  GSK_PROTOCOL_TLSV1_ON:
                   GSK_PROTOCOL_TLSV1_OFF);
   if(cc == CURLE_OK)
     cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
index 2d4bf9e9c87de805850c28a2633f1168c9956fda..34dfbb1a7a297c24b18f0cfc6d8a54f25c126afc 100644 (file)
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1267,6 +1267,12 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
   case CURL_SSLVERSION_SSLv3:
     ssl3 = PR_TRUE;
     break;
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+    failf(data, "TLS minor version cannot be set\n");
+    curlerr = CURLE_SSL_CONNECT_ERROR;
+    goto error;
   }
 
   if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess)
index b8a8daecac81e55b17ddd8f14bb7fe208e9716f6..42bf890fce29b6db7afcb6b404847e9b2580b1a0 100644 (file)
@@ -204,6 +204,12 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
   case CURL_SSLVERSION_SSLv3:
     h->protocol = SSL_VERSION_3;
     break;
+
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+    failf(data, "TLS minor version cannot be set");
+    return CURLE_SSL_CONNECT_ERROR;
   }
 
   h->peerCert = NULL;
index c747420f600c0c7393c94c9ae738f68ec36036cb..84fd7373858a35c8c83a8edbee8f2b74c93d9d8d 100644 (file)
@@ -1431,19 +1431,12 @@ ossl_connect_step1(struct connectdata *conn,
   switch(data->set.ssl.version) {
   default:
   case CURL_SSLVERSION_DEFAULT:
-#ifdef USE_TLS_SRP
-    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
-      infof(data, "Set version TLSv1 for SRP authorisation\n");
-      req_method = TLSv1_client_method() ;
-    }
-    else
-#endif
-    /* we try to figure out version */
-    req_method = SSLv23_client_method();
-    use_sni(TRUE);
-    break;
   case CURL_SSLVERSION_TLSv1:
-    req_method = TLSv1_client_method();
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+    /* it will be handled later with the context options */
+    req_method = SSLv23_client_method();
     use_sni(TRUE);
     break;
   case CURL_SSLVERSION_SSLv2:
@@ -1556,9 +1549,39 @@ ossl_connect_step1(struct connectdata *conn,
     ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
 #endif
 
-  /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
-  if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
+  switch(data->set.ssl.version) {
+  case CURL_SSLVERSION_DEFAULT:
+    ctx_options |= SSL_OP_NO_SSLv2;
+#ifdef USE_TLS_SRP
+    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+      infof(data, "Set version TLSv1.x for SRP authorisation\n");
+      ctx_options |= SSL_OP_NO_SSLv3;
+    }
+#endif
+    break;
+  case CURL_SSLVERSION_TLSv1:
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
     ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    ctx_options |= SSL_OP_NO_TLSv1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    ctx_options |= SSL_OP_NO_TLSv1;
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    break;
+  }
 
   SSL_CTX_set_options(connssl->ctx, ctx_options);
 
index 1015843cd72470dfa09d9a3024b5d7e78233db3c..b14d84f8398e599789a93a8fec896ca8b79d0640 100644 (file)
      d                 c                   2
      d CURL_SSLVERSION_SSLv3...
      d                 c                   3
+     d CURL_SSLVERSION_TLSv1_0...
+     d                 c                   4
+     d CURL_SSLVERSION_TLSv1_1...
+     d                 c                   5
+     d CURL_SSLVERSION_TLSv1_2...
+     d                 c                   6
       *
      d CURL_TLSAUTH_NONE...
      d                 c                   0
index 6a405ff412e7ce4d8482a1e34da7efa3b5b9f2ef..d0feb71ed9063dda5d12eeb937c3a0d51f6c85ab 100644 (file)
@@ -184,6 +184,9 @@ static const struct LongShort aliases[]= {
   {"01",  "http1.1",                 FALSE},
   {"02",  "http2.0",                 FALSE},
   {"1",  "tlsv1",                    FALSE},
+  {"10",  "tlsv1.0",                 FALSE},
+  {"11",  "tlsv1.1",                 FALSE},
+  {"12",  "tlsv1.2",                 FALSE},
   {"2",  "sslv2",                    FALSE},
   {"3",  "sslv3",                    FALSE},
   {"4",  "ipv4",                     FALSE},
@@ -1023,9 +1026,25 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
         break;
       }
       break;
-    case '1':
-      /* TLS version 1 */
-      config->ssl_version = CURL_SSLVERSION_TLSv1;
+    case '1': /* --tlsv1* options */
+      switch(subletter) {
+      case '\0':
+        /* TLS version 1.x */
+        config->ssl_version = CURL_SSLVERSION_TLSv1;
+        break;
+      case '0':
+        /* TLS version 1.0 */
+        config->ssl_version = CURL_SSLVERSION_TLSv1_0;
+        break;
+      case '1':
+        /* TLS version 1.1 */
+        config->ssl_version = CURL_SSLVERSION_TLSv1_1;
+        break;
+      case '2':
+        /* TLS version 1.2 */
+        config->ssl_version = CURL_SSLVERSION_TLSv1_2;
+        break;
+      }
       break;
     case '2':
       /* SSL version 2 */
index cb93e1117ffdfd92d847f30296798456d2c8d479..f29bcd6190a79e4f75b30961486acbd7f6737b1c 100644 (file)
@@ -78,6 +78,9 @@ const NameValue setopt_nv_CURL_SSLVERSION[] = {
   NV(CURL_SSLVERSION_TLSv1),
   NV(CURL_SSLVERSION_SSLv2),
   NV(CURL_SSLVERSION_SSLv3),
+  NV(CURL_SSLVERSION_TLSv1_0),
+  NV(CURL_SSLVERSION_TLSv1_1),
+  NV(CURL_SSLVERSION_TLSv1_2),
   NVEND,
 };