Blob Blame History Raw
From e3e370c5257ac21c57a59b72fa2810c823eb8984 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 29 Jan 2014 12:55:36 +0100
Subject: [PATCH 01/20] nss: do not fail if NSS does not implement a cipher

... that the user does not ask for

Upstream-commit: e15e73b741a2ddc88d166d2cec86d2bebb5d349e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 40daee3..e5804be 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -196,14 +196,13 @@ static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model,
   PRBool cipher_state[NUM_OF_CIPHERS];
   PRBool found;
   char *cipher;
-  SECStatus rv;
 
   /* First disable all ciphers. This uses a different max value in case
    * NSS adds more ciphers later we don't want them available by
    * accident
    */
   for(i=0; i<SSL_NumImplementedCiphers; i++) {
-    SSL_CipherPrefSet(model, SSL_ImplementedCiphers[i], SSL_NOT_ALLOWED);
+    SSL_CipherPrefSet(model, SSL_ImplementedCiphers[i], PR_FALSE);
   }
 
   /* Set every entry in our list to false */
@@ -243,8 +242,10 @@ static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model,
 
   /* Finally actually enable the selected ciphers */
   for(i=0; i<NUM_OF_CIPHERS; i++) {
-    rv = SSL_CipherPrefSet(model, cipherlist[i].num, cipher_state[i]);
-    if(rv != SECSuccess) {
+    if(!cipher_state[i])
+      continue;
+
+    if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
       failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
       return SECFailure;
     }
-- 
2.1.0


From 14686a8b987efe6915fe2a4a1f191d10cdc504ce Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 29 Jan 2014 13:03:46 +0100
Subject: [PATCH 02/20] nss: do not use the NSS_ENABLE_ECC define

It is not provided by NSS public headers.

Bug: https://bugzilla.redhat.com/1058776

Upstream-commit: 665c160f0a4635565b44704ca281d2a03e715d6d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index e5804be..9561bed 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -126,7 +126,6 @@ static const cipher_s cipherlist[] = {
   /* AES ciphers. */
   {"rsa_aes_128_sha",            TLS_RSA_WITH_AES_128_CBC_SHA},
   {"rsa_aes_256_sha",            TLS_RSA_WITH_AES_256_CBC_SHA},
-#ifdef NSS_ENABLE_ECC
   /* ECC ciphers. */
   {"ecdh_ecdsa_null_sha",        TLS_ECDH_ECDSA_WITH_NULL_SHA},
   {"ecdh_ecdsa_rc4_128_sha",     TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
@@ -153,7 +152,6 @@ static const cipher_s cipherlist[] = {
   {"ecdh_anon_3des_sha",         TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
   {"ecdh_anon_aes_128_sha",      TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
   {"ecdh_anon_aes_256_sha",      TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
-#endif
 };
 
 /* following ciphers are new in NSS 3.4 and not enabled by default, therefore
-- 
2.1.0


From e3a4fdbf6a29be442c1d444eef3d1fa05706490c Mon Sep 17 00:00:00 2001
From: Gergely Nagy <ngg@tresorit.com>
Date: Thu, 19 Sep 2013 15:17:13 +0200
Subject: [PATCH 03/20] SSL: protocol version can be specified more precisely

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).

NSS:
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.

Upstream-commit: ad34a2d5c87c7f4b14e8dded34569395de0d8c5b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 docs/libcurl/curl_easy_setopt.3  |  8 ++++++-
 docs/libcurl/symbols-in-versions |  3 +++
 include/curl/curl.h              |  5 +++-
 lib/nss.c                        |  6 +++++
 lib/ssluse.c                     | 49 ++++++++++++++++++++++++++++++----------
 src/tool_getparam.c              | 25 +++++++++++++++++---
 src/tool_setopt.c                |  3 +++
 7 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index bebf8c0..1fcccdb 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -2365,7 +2365,13 @@ 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_TLSv1_0
+Force TLSv1.0
+.IP CURL_SSLVERSION_TLSv1_1
+Force TLSv1.1
+.IP CURL_SSLVERSION_TLSv1_2
+Force TLSv1.2
 .IP CURL_SSLVERSION_SSLv2
 Force SSLv2
 .IP CURL_SSLVERSION_SSLv3
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index e61cbbe..79aaaba 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -689,6 +689,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
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 41c0881..000764b 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1640,9 +1640,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 */
 };
diff --git a/lib/nss.c b/lib/nss.c
index 9561bed..a1cf3a1 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1389,6 +1389,12 @@ static CURLcode nss_setup_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)
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 69328f6..e7d1eff 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -1374,19 +1374,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:
@@ -1501,7 +1494,39 @@ ossl_connect_step1(struct connectdata *conn,
 
   /* 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);
 
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 5eb2c9f..603ba7b 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -176,6 +176,9 @@ static const struct LongShort aliases[]= {
   {"$K", "sasl-ir",                  FALSE},
   {"0",  "http1.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},
@@ -976,9 +979,25 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
       /* HTTP version 1.0 */
       config->httpversion = CURL_HTTP_VERSION_1_0;
       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 */
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index cb93e11..f29bcd6 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -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,
 };
 
-- 
2.1.0


From 51081768a70fe880e01c7100a8b7c386e45ce91b Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 15 Oct 2013 20:31:04 +0200
Subject: [PATCH 04/20] curl: document the new --tlsv1.[012] options

Upstream-commit: 076726f1412205622414abd908723c4b33ca12cb
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 docs/curl.1 | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/docs/curl.1 b/docs/curl.1
index 9e1a688..e6eda68 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -118,6 +118,18 @@ internally preferred: HTTP 1.1.
 .IP "-1, --tlsv1"
 (SSL)
 Forces curl to use TLS version 1 when negotiating with a remote TLS server.
+.IP "--tlsv1.0"
+(SSL)
+Forces curl to use TLS version 1.0 when negotiating with a remote TLS server.
+(Added in 7.34.0)
+.IP "--tlsv1.1"
+(SSL)
+Forces curl to use TLS version 1.1 when negotiating with a remote TLS server.
+(Added in 7.34.0)
+.IP "--tlsv1.2"
+(SSL)
+Forces curl to use TLS version 1.2 when negotiating with a remote TLS server.
+(Added in 7.34.0)
 .IP "-2, --sslv2"
 (SSL)
 Forces curl to use SSL version 2 when negotiating with a remote SSL server.
-- 
2.1.0


From da154f6a99ada8bdbc8ccd347fd34fd471670c75 Mon Sep 17 00:00:00 2001
From: Steve Holme <steve_holme@hotmail.com>
Date: Wed, 16 Oct 2013 20:06:23 +0100
Subject: [PATCH 05/20] SSL: Corrected version number for new symbols from
 commit ad34a2d5c87c7f

Upstream-commit: 2c84ffe1549ea7d5029ba7863f53013562e6758d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 docs/libcurl/symbols-in-versions | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index 79aaaba..21c784e 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -689,9 +689,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_SSLVERSION_TLSv1_0         7.34.0
+CURL_SSLVERSION_TLSv1_1         7.34.0
+CURL_SSLVERSION_TLSv1_2         7.34.0
 CURL_TIMECOND_IFMODSINCE        7.9.7
 CURL_TIMECOND_IFUNMODSINCE      7.9.7
 CURL_TIMECOND_LASTMOD           7.9.7
-- 
2.1.0


From 169ff20b5c260a3700ec348c3539b22621b1196d Mon Sep 17 00:00:00 2001
From: Steve Holme <steve_holme@hotmail.com>
Date: Wed, 16 Oct 2013 20:18:15 +0100
Subject: [PATCH 06/20] DOCS: Added libcurl version number to
 CURLOPT_SSLVERSION

Upstream-commit: 75b9b26465d5f01b52564293c2d553649f801f70
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 docs/libcurl/curl_easy_setopt.3 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 1fcccdb..6f72795 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -2366,11 +2366,11 @@ 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.x
-.IP CURL_SSLVERSION_TLSv1_0
+.IP CURL_SSLVERSION_TLSv1_0 (Added in 7.34.0)
 Force TLSv1.0
-.IP CURL_SSLVERSION_TLSv1_1
+.IP CURL_SSLVERSION_TLSv1_1 (Added in 7.34.0)
 Force TLSv1.1
-.IP CURL_SSLVERSION_TLSv1_2
+.IP CURL_SSLVERSION_TLSv1_2 (Added in 7.34.0)
 Force TLSv1.2
 .IP CURL_SSLVERSION_SSLv2
 Force SSLv2
-- 
2.1.0


From 71ab9b6a2241785bac59be8cdb49c195af5b1d48 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 25 Nov 2013 16:03:52 +0100
Subject: [PATCH 07/20] nss: use a better API for controlling SSL version

This change introduces a dependency on NSS 3.14+.

Upstream-commit: 30e7e7552ba4397896ecac82ea04f38d52c4cc8f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 configure      | 20 ++++++++++----------
 configure.ac   |  4 ++--
 docs/INTERNALS |  2 +-
 lib/nss.c      | 30 +++++++++++++-----------------
 4 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/configure b/configure
index 618bea8..22bd975 100755
--- a/configure
+++ b/configure
@@ -23886,9 +23886,9 @@ $as_echo "found" >&6; }
          CPPFLAGS="$CPPFLAGS $addcflags"
       fi
 
-            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PK11_CreateGenericObject in -lnss3" >&5
-$as_echo_n "checking for PK11_CreateGenericObject in -lnss3... " >&6; }
-if ${ac_cv_lib_nss3_PK11_CreateGenericObject+:} false; then :
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_VersionRangeSet in -lnss3" >&5
+$as_echo_n "checking for SSL_VersionRangeSet in -lnss3... " >&6; }
+if ${ac_cv_lib_nss3_SSL_VersionRangeSet+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23900,26 +23900,26 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char PK11_CreateGenericObject ();
+char SSL_VersionRangeSet ();
 int main (void)
 {
-return PK11_CreateGenericObject ();
+return SSL_VersionRangeSet ();
  ;
  return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_nss3_PK11_CreateGenericObject=yes
+  ac_cv_lib_nss3_SSL_VersionRangeSet=yes
 else
-  ac_cv_lib_nss3_PK11_CreateGenericObject=no
+  ac_cv_lib_nss3_SSL_VersionRangeSet=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nss3_PK11_CreateGenericObject" >&5
-$as_echo "$ac_cv_lib_nss3_PK11_CreateGenericObject" >&6; }
-if test "x$ac_cv_lib_nss3_PK11_CreateGenericObject" = xyes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nss3_SSL_VersionRangeSet" >&5
+$as_echo "$ac_cv_lib_nss3_SSL_VersionRangeSet" >&6; }
+if test "x$ac_cv_lib_nss3_SSL_VersionRangeSet" = xyes; then :
 
 
 $as_echo "#define USE_NSS 1" >>confdefs.h
diff --git a/configure.ac b/configure.ac
index 00ffe5c..f30db56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2163,8 +2163,8 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
          CPPFLAGS="$CPPFLAGS $addcflags"
       fi
 
-      dnl The function PK11_CreateGenericObject is needed to load libnsspem.so
-      AC_CHECK_LIB(nss3, PK11_CreateGenericObject,
+      dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0
+      AC_CHECK_LIB(nss3, SSL_VersionRangeSet,
        [
        AC_DEFINE(USE_NSS, 1, [if NSS is enabled])
        AC_SUBST(USE_NSS, [1])
diff --git a/docs/INTERNALS b/docs/INTERNALS
index 66e11a4..c8e433c 100644
--- a/docs/INTERNALS
+++ b/docs/INTERNALS
@@ -43,7 +43,7 @@ Portability
  openldap     2.0
  MIT krb5 lib 1.2.4
  qsossl       V5R3M0
- NSS          3.12.x
+ NSS          3.14.x
  axTLS        1.2.7
  Heimdal      ?
 
diff --git a/lib/nss.c b/lib/nss.c
index a1cf3a1..7d1e52e 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1303,9 +1303,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   PRFileDesc *model = NULL;
   PRFileDesc *nspr_io = NULL;
   PRFileDesc *nspr_io_stub = NULL;
-  PRBool ssl2 = PR_FALSE;
-  PRBool ssl3 = PR_FALSE;
-  PRBool tlsv1 = PR_FALSE;
+  SSLVersionRange sslver;
   PRBool ssl_no_cache;
   PRBool ssl_cbc_random_iv;
   struct SessionHandle *data = conn->data;
@@ -1374,20 +1372,25 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   switch (data->set.ssl.version) {
   default:
   case CURL_SSLVERSION_DEFAULT:
-    ssl3 = PR_TRUE;
-    if(data->state.ssl_connect_retry)
+    sslver.min = SSL_LIBRARY_VERSION_3_0;
+    if(data->state.ssl_connect_retry) {
       infof(data, "TLS disabled due to previous handshake failure\n");
+      sslver.max = SSL_LIBRARY_VERSION_3_0;
+    }
     else
-      tlsv1 = PR_TRUE;
+      sslver.max = SSL_LIBRARY_VERSION_TLS_1_0;
     break;
   case CURL_SSLVERSION_TLSv1:
-    tlsv1 = PR_TRUE;
+    sslver.min = SSL_LIBRARY_VERSION_TLS_1_0;
+    sslver.max = SSL_LIBRARY_VERSION_TLS_1_0;
     break;
   case CURL_SSLVERSION_SSLv2:
-    ssl2 = PR_TRUE;
+    sslver.min = SSL_LIBRARY_VERSION_2;
+    sslver.max = SSL_LIBRARY_VERSION_2;
     break;
   case CURL_SSLVERSION_SSLv3:
-    ssl3 = PR_TRUE;
+    sslver.min = SSL_LIBRARY_VERSION_3_0;
+    sslver.max = SSL_LIBRARY_VERSION_3_0;
     break;
   case CURL_SSLVERSION_TLSv1_0:
   case CURL_SSLVERSION_TLSv1_1:
@@ -1397,14 +1400,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     goto error;
   }
 
-  if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess)
-    goto error;
-  if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess)
-    goto error;
-  if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess)
-    goto error;
-
-  if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
+  if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
     goto error;
 
   ssl_cbc_random_iv = !data->set.ssl_enable_beast;
-- 
2.1.0


From b1f68362d6936af6d731bea7c776ec7cc593f012 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 25 Nov 2013 16:14:55 +0100
Subject: [PATCH 08/20] nss: put SSL version selection into separate fnc

Upstream-commit: 4fb8241add5b68e95fbf44d3c2bf470201a9915d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 72 +++++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 42 insertions(+), 30 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 7d1e52e..e9aec93 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1244,6 +1244,46 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
   return CURLE_OK;
 }
 
+static CURLcode nss_init_sslver(SSLVersionRange *sslver,
+                                struct SessionHandle *data)
+{
+  switch (data->set.ssl.version) {
+  default:
+  case CURL_SSLVERSION_DEFAULT:
+    sslver->min = SSL_LIBRARY_VERSION_3_0;
+    if(data->state.ssl_connect_retry) {
+      infof(data, "TLS disabled due to previous handshake failure\n");
+      sslver->max = SSL_LIBRARY_VERSION_3_0;
+    }
+    else
+      sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_TLSv1:
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_SSLv2:
+    sslver->min = SSL_LIBRARY_VERSION_2;
+    sslver->max = SSL_LIBRARY_VERSION_2;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_SSLv3:
+    sslver->min = SSL_LIBRARY_VERSION_3_0;
+    sslver->max = SSL_LIBRARY_VERSION_3_0;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+    break;
+  }
+
+  failf(data, "TLS minor version cannot be set");
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
 static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
                                  struct SessionHandle *data,
                                  CURLcode curlerr)
@@ -1369,37 +1409,9 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
     goto error;
 
-  switch (data->set.ssl.version) {
-  default:
-  case CURL_SSLVERSION_DEFAULT:
-    sslver.min = SSL_LIBRARY_VERSION_3_0;
-    if(data->state.ssl_connect_retry) {
-      infof(data, "TLS disabled due to previous handshake failure\n");
-      sslver.max = SSL_LIBRARY_VERSION_3_0;
-    }
-    else
-      sslver.max = SSL_LIBRARY_VERSION_TLS_1_0;
-    break;
-  case CURL_SSLVERSION_TLSv1:
-    sslver.min = SSL_LIBRARY_VERSION_TLS_1_0;
-    sslver.max = SSL_LIBRARY_VERSION_TLS_1_0;
-    break;
-  case CURL_SSLVERSION_SSLv2:
-    sslver.min = SSL_LIBRARY_VERSION_2;
-    sslver.max = SSL_LIBRARY_VERSION_2;
-    break;
-  case CURL_SSLVERSION_SSLv3:
-    sslver.min = SSL_LIBRARY_VERSION_3_0;
-    sslver.max = SSL_LIBRARY_VERSION_3_0;
-    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;
+  /* enable/disable the requested SSL version(s) */
+  if(nss_init_sslver(&sslver, data) != CURLE_OK)
     goto error;
-  }
-
   if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
     goto error;
 
-- 
2.1.0


From 7dabbab8da3cb8f1551ba38ef8297201b70ca7e8 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 25 Nov 2013 16:25:15 +0100
Subject: [PATCH 09/20] nss: allow to use TLS > 1.0 if built against recent NSS

Bug: http://curl.haxx.se/mail/lib-2013-11/0162.html
Upstream-commit: 7fc9325a52a6dad1f8b859a3269472ffc125edd0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/lib/nss.c b/lib/nss.c
index e9aec93..836f3dc 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1261,7 +1261,13 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
 
   case CURL_SSLVERSION_TLSv1:
     sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
+#elif defined SSL_LIBRARY_VERSION_TLS_1_1
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
+#else
     sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+#endif
     return CURLE_OK;
 
   case CURL_SSLVERSION_SSLv2:
@@ -1275,8 +1281,24 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
     return CURLE_OK;
 
   case CURL_SSLVERSION_TLSv1_0:
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+    return CURLE_OK;
+
   case CURL_SSLVERSION_TLSv1_1:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_1
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_1;
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
+    return CURLE_OK;
+#endif
+    break;
+
   case CURL_SSLVERSION_TLSv1_2:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_2;
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
+    return CURLE_OK;
+#endif
     break;
   }
 
-- 
2.1.0


From b31985288d9d55817f80386c9604799c6a42a5d3 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 2 Dec 2013 14:25:07 +0100
Subject: [PATCH 10/20] nss: unconditionally require NSS_InitContext()

... since we depend on NSS 3.14+ because of SSL_VersionRangeSet() anyway

[upstream commit 865666afca926faa1c721020fc54364540caf734]
---
 configure    | 12 ------------
 configure.ac |  8 --------
 lib/nss.c    | 26 --------------------------
 3 files changed, 46 deletions(-)

diff --git a/configure b/configure
index 22bd975..5c73288 100755
--- a/configure
+++ b/configure
@@ -23942,18 +23942,6 @@ fi
         { $as_echo "$as_me:${as_lineno-$LINENO}: detected NSS version $version" >&5
 $as_echo "$as_me: detected NSS version $version" >&6;}
 
-                        ac_fn_c_check_func "$LINENO" "NSS_InitContext" "ac_cv_func_NSS_InitContext"
-if test "x$ac_cv_func_NSS_InitContext" = xyes; then :
-
-
-$as_echo "#define HAVE_NSS_INITCONTEXT 1" >>confdefs.h
-
-          HAVE_NSS_INITCONTEXT=1
-
-
-fi
-
-
                                         if test "x$cross_compiling" != "xyes"; then
           LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$nssprefix/lib$libsuff"
           export LD_LIBRARY_PATH
diff --git a/configure.ac b/configure.ac
index f30db56..ed0965a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2180,14 +2180,6 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
       if test "x$USE_NSS" = "xyes"; then
         AC_MSG_NOTICE([detected NSS version $version])
 
-        dnl NSS_InitContext() was introduced in NSS 3.12.5 and helps to prevent
-        dnl collisions on NSS initialization/shutdown with other libraries
-        AC_CHECK_FUNC(NSS_InitContext,
-        [
-          AC_DEFINE(HAVE_NSS_INITCONTEXT, 1, [if you have the NSS_InitContext function])
-          AC_SUBST(HAVE_NSS_INITCONTEXT, [1])
-        ])
-
         dnl when shared libs were found in a path that the run-time
         dnl linker doesn't search through, we need to add it to
         dnl LD_LIBRARY_PATH to prevent further configure tests to fail
diff --git a/lib/nss.c b/lib/nss.c
index 836f3dc..36244c2 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -76,9 +76,7 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
 
 PRLock * nss_initlock = NULL;
 PRLock * nss_crllock = NULL;
-#ifdef HAVE_NSS_INITCONTEXT
 NSSInitContext * nss_context = NULL;
-#endif
 
 volatile int initialized = 0;
 
@@ -911,7 +909,6 @@ static PRStatus nspr_io_close(PRFileDesc *fd)
 
 static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
 {
-#ifdef HAVE_NSS_INITCONTEXT
   NSSInitParameters initparams;
 
   if(nss_context != NULL)
@@ -919,12 +916,6 @@ static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
 
   memset((void *) &initparams, '\0', sizeof(initparams));
   initparams.length = sizeof(initparams);
-#else /* HAVE_NSS_INITCONTEXT */
-  SECStatus rv;
-
-  if(NSS_IsInitialized())
-    return CURLE_OK;
-#endif
 
   if(cert_dir) {
     const bool use_sql = NSS_VersionCheck("3.12.0");
@@ -933,35 +924,22 @@ static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
       return CURLE_OUT_OF_MEMORY;
 
     infof(data, "Initializing NSS with certpath: %s\n", certpath);
-#ifdef HAVE_NSS_INITCONTEXT
     nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
             NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
     free(certpath);
 
     if(nss_context != NULL)
       return CURLE_OK;
-#else /* HAVE_NSS_INITCONTEXT */
-    rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
-    free(certpath);
-
-    if(rv == SECSuccess)
-      return CURLE_OK;
-#endif
 
     infof(data, "Unable to initialize NSS database\n");
   }
 
   infof(data, "Initializing NSS with certpath: none\n");
-#ifdef HAVE_NSS_INITCONTEXT
   nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
          | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
          | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
   if(nss_context != NULL)
     return CURLE_OK;
-#else /* HAVE_NSS_INITCONTEXT */
-  if(NSS_NoDB_Init(NULL) == SECSuccess)
-    return CURLE_OK;
-#endif
 
   infof(data, "Unable to initialize NSS\n");
   return CURLE_SSL_CACERT_BADFILE;
@@ -1072,12 +1050,8 @@ void Curl_nss_cleanup(void)
       SECMOD_DestroyModule(mod);
       mod = NULL;
     }
-#ifdef HAVE_NSS_INITCONTEXT
     NSS_ShutdownContext(nss_context);
     nss_context = NULL;
-#else /* HAVE_NSS_INITCONTEXT */
-    NSS_Shutdown();
-#endif
   }
   PR_Unlock(nss_initlock);
 
-- 
2.1.0


From 94ec77e2a2dbe42e040c419de44a1cd5368c4908 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 2 Dec 2013 17:00:35 +0100
Subject: [PATCH 11/20] tool_metalink: do not use HAVE_NSS_INITCONTEXT

... no longer provided by the configure script

Upstream-commit: ff9b66a8d4abb2fd92b12ae8ae3e4e7f39856af7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 src/tool_metalink.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index be5fc26..050f59d 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -54,9 +54,7 @@
 #  define MD5_CTX    void *
 #  define SHA_CTX    void *
 #  define SHA256_CTX void *
-#  ifdef HAVE_NSS_INITCONTEXT
-     static NSSInitContext *nss_context;
-#  endif
+   static NSSInitContext *nss_context;
 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
               (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
       (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
@@ -240,7 +238,6 @@ static int nss_hash_init(void **pctx, SECOidTag hash_alg)
   PK11Context *ctx;
 
   /* we have to initialize NSS if not initialized alraedy */
-#ifdef HAVE_NSS_INITCONTEXT
   if(!NSS_IsInitialized() && !nss_context) {
     static NSSInitParameters params;
     params.length = sizeof params;
@@ -248,7 +245,6 @@ static int nss_hash_init(void **pctx, SECOidTag hash_alg)
         | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
         | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
   }
-#endif
 
   ctx = PK11_CreateDigestContext(hash_alg);
   if(!ctx)
@@ -894,7 +890,7 @@ void clean_metalink(struct Configurable *config)
 
 void metalink_cleanup(void)
 {
-#if defined(USE_NSS) && defined(HAVE_NSS_INITCONTEXT)
+#ifdef USE_NSS
   if(nss_context) {
     NSS_ShutdownContext(nss_context);
     nss_context = NULL;
-- 
2.1.0


From 087dcd05bc4dc7f7d2665377d4827f2b817446aa Mon Sep 17 00:00:00 2001
From: Fabian Frank <fabian@pagefault.de>
Date: Thu, 6 Feb 2014 00:41:53 -0800
Subject: [PATCH 12/20] nss: prefer highest available TLS version

Offer TLSv1.0 to 1.2 by default, still fall back to SSLv3
if --tlsv1[.N] was not specified on the command line.

Upstream-commit: ff92fcfb907b6aa69bc7e35670797fc0440756bd
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/nss.c b/lib/nss.c
index 36244c2..503aa9a 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1228,10 +1228,11 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
     if(data->state.ssl_connect_retry) {
       infof(data, "TLS disabled due to previous handshake failure\n");
       sslver->max = SSL_LIBRARY_VERSION_3_0;
+      return CURLE_OK;
     }
     else
       sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
-    return CURLE_OK;
+  /* intentional fall-through to default to highest TLS version if possible */
 
   case CURL_SSLVERSION_TLSv1:
     sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
-- 
2.1.0


From 2eb968240627d3b7bbd188db5548ccc73621e018 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 2 Dec 2013 16:09:12 +0100
Subject: [PATCH 13/20] nss: make sure that 'sslver' is always initialized

Upstream-commit: e221b55f67a2e12717e911f25d1bb6c85fcebfab
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 503aa9a..87b883a 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1230,12 +1230,9 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
       sslver->max = SSL_LIBRARY_VERSION_3_0;
       return CURLE_OK;
     }
-    else
-      sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
   /* intentional fall-through to default to highest TLS version if possible */
 
   case CURL_SSLVERSION_TLSv1:
-    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
 #ifdef SSL_LIBRARY_VERSION_TLS_1_2
     sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
 #elif defined SSL_LIBRARY_VERSION_TLS_1_1
@@ -1340,7 +1337,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   PRFileDesc *model = NULL;
   PRFileDesc *nspr_io = NULL;
   PRFileDesc *nspr_io_stub = NULL;
-  SSLVersionRange sslver;
   PRBool ssl_no_cache;
   PRBool ssl_cbc_random_iv;
   struct SessionHandle *data = conn->data;
@@ -1349,6 +1345,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   CURLcode curlerr;
   const int *cipher_to_enable;
 
+  SSLVersionRange sslver = {
+    SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
+    SSL_LIBRARY_VERSION_TLS_1_0   /* max */
+  };
+
   connssl->data = data;
 
   /* list of all NSS objects we need to destroy in Curl_nss_close() */
-- 
2.1.0


From b7dc3a64f687152015ef791e17e0d69b4d6c0484 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 7 Feb 2014 20:28:53 +0100
Subject: [PATCH 14/20] --help: add missing --tlsv1.x options

Upstream-commit: 67d14ab98f8b819ee6f5e6a4a2770d311c6bf13b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 src/tool_help.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/tool_help.c b/src/tool_help.c
index 64534ac..f00ff55 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -200,7 +200,10 @@ static const char *const helptext[] = {
   " -t, --telnet-option OPT=VAL  Set telnet option",
   "     --tftp-blksize VALUE  Set TFTP BLKSIZE option (must be >512)",
   " -z, --time-cond TIME  Transfer based on a time condition",
-  " -1, --tlsv1         Use TLSv1 (SSL)",
+  " -1/--tlsv1          Use => TLSv1 (SSL)",
+  "    --tlsv1.0        Use TLSv1.0 (SSL)",
+  "    --tlsv1.1        Use TLSv1.1 (SSL)",
+  "    --tlsv1.2        Use TLSv1.2 (SSL)",
   "     --trace FILE    Write a debug trace to the given file",
   "     --trace-ascii FILE  Like --trace but without the hex output",
   "     --trace-time    Add time stamps to trace/verbose output",
-- 
2.1.0


From 2d2447ecab5ac7a51409eb51ee417841500b8732 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 17 Feb 2014 16:55:10 +0100
Subject: [PATCH 15/20] curl.1: update the description of --tlsv1

... and mention the --tlsv1.[0-2] options in the --tslv1 entry

Reported-by: Hubert Kario
Upstream-commit: 03c288202ed159a2a9e953f59e58f69a86eda79b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 docs/curl.1 | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/docs/curl.1 b/docs/curl.1
index e6eda68..3458024 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -117,7 +117,10 @@ more informational, meter.
 internally preferred: HTTP 1.1.
 .IP "-1, --tlsv1"
 (SSL)
-Forces curl to use TLS version 1 when negotiating with a remote TLS server.
+Forces curl to use TLS version 1.x when negotiating with a remote TLS server.
+You can use options \fI--tlsv1.0\fP, \fI--tlsv1.1\fP, and \fI--tlsv1.2\fP to
+control the TLS version more precisely (if the SSL backend in use supports such
+a level of control).
 .IP "--tlsv1.0"
 (SSL)
 Forces curl to use TLS version 1.0 when negotiating with a remote TLS server.
-- 
2.1.0


From b4e3330f82d2c0413f17ca8f1f811de13fd8fd35 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 2 Jul 2014 17:37:43 +0200
Subject: [PATCH 16/20] nss: do not abort on connection failure

... due to calling SSL_VersionRangeGet() with NULL file descriptor

Reported-by: upstream tests 305 and 404
Upstream-commit: 7c21558503cbb10595c345acc7820cb9dc8741d6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/nss.c b/lib/nss.c
index 87b883a..bed87c2 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1305,7 +1305,8 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
   Curl_llist_destroy(connssl->obj_list, NULL);
   connssl->obj_list = NULL;
 
-  if((SSL_VersionRangeGet(connssl->handle, &sslver) == SECSuccess)
+  if(connssl->handle
+      && (SSL_VersionRangeGet(connssl->handle, &sslver) == SECSuccess)
       && (sslver.min == SSL_LIBRARY_VERSION_3_0)
       && (sslver.max == SSL_LIBRARY_VERSION_TLS_1_0)
       && isTLSIntoleranceError(err)) {
-- 
2.1.0


From a5fd46ad1acbac7c4cd2b16a494d834a5bb117c3 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 2 Jul 2014 17:49:37 +0200
Subject: [PATCH 17/20] nss: make the fallback to SSLv3 work again

This feature was unintentionally disabled by commit ff92fcfb.

Upstream-commit: 7581dee10aedeb96231dd24e187ff5426fc72469
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/nss.c b/lib/nss.c
index bed87c2..bd7aa27 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1308,7 +1308,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
   if(connssl->handle
       && (SSL_VersionRangeGet(connssl->handle, &sslver) == SECSuccess)
       && (sslver.min == SSL_LIBRARY_VERSION_3_0)
-      && (sslver.max == SSL_LIBRARY_VERSION_TLS_1_0)
+      && (sslver.max != SSL_LIBRARY_VERSION_3_0)
       && isTLSIntoleranceError(err)) {
     /* schedule reconnect through Curl_retry_request() */
     data->state.ssl_connect_retry = TRUE;
-- 
2.1.0


From c53ff38515729174c37bfd9e090f08027f107a05 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:02:03 +0100
Subject: [PATCH 18/20] nss: do not enable AES cipher-suites by default

... but allow them to be enabled/disabled explicitly.  The default
policy should be maintained at the NSS level.

Upstream-commit: b4f6cd46eb1b5a98573e0c0e619dc71646affdc8
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 27 ++++-----------------------
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index bd7aa27..a0cd619 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -122,6 +122,10 @@ static const cipher_s cipherlist[] = {
   {"rsa_des_56_sha",             TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
   {"rsa_rc4_56_sha",             TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
   /* AES ciphers. */
+  {"dhe_dss_aes_128_cbc_sha",    TLS_DHE_DSS_WITH_AES_128_CBC_SHA},
+  {"dhe_dss_aes_256_cbc_sha",    TLS_DHE_DSS_WITH_AES_256_CBC_SHA},
+  {"dhe_rsa_aes_128_cbc_sha",    TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
+  {"dhe_rsa_aes_256_cbc_sha",    TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
   {"rsa_aes_128_sha",            TLS_RSA_WITH_AES_128_CBC_SHA},
   {"rsa_aes_256_sha",            TLS_RSA_WITH_AES_256_CBC_SHA},
   /* ECC ciphers. */
@@ -152,18 +156,6 @@ static const cipher_s cipherlist[] = {
   {"ecdh_anon_aes_256_sha",      TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
 };
 
-/* following ciphers are new in NSS 3.4 and not enabled by default, therefore
-   they are enabled explicitly */
-static const int enable_ciphers_by_default[] = {
-  TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
-  TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
-  TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
-  TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
-  TLS_RSA_WITH_AES_128_CBC_SHA,
-  TLS_RSA_WITH_AES_256_CBC_SHA,
-  SSL_NULL_WITH_NULL_NULL
-};
-
 static const char* pem_library = "libnsspem.so";
 SECMODModule* mod = NULL;
 
@@ -1344,7 +1336,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   CURLcode curlerr;
-  const int *cipher_to_enable;
 
   SSLVersionRange sslver = {
     SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
@@ -1429,16 +1420,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   /* reset the flag to avoid an infinite loop */
   data->state.ssl_connect_retry = FALSE;
 
-  /* enable all ciphers from enable_ciphers_by_default */
-  cipher_to_enable = enable_ciphers_by_default;
-  while(SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) {
-    if(SSL_CipherPrefSet(model, *cipher_to_enable, PR_TRUE) != SECSuccess) {
-      curlerr = CURLE_SSL_CIPHER;
-      goto error;
-    }
-    cipher_to_enable++;
-  }
-
   if(data->set.ssl.cipher_list) {
     if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
       curlerr = CURLE_SSL_CIPHER;
-- 
2.1.0


From 173e2f454c5ae2e73d8d0a0ed8528fcf2ca7440d Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:10:54 +0100
Subject: [PATCH 19/20] nss: allow to enable/disable new HMAC-SHA256
 cipher-suites

... if built against a new enough version of NSS

Upstream-commit: c864d81289297b04dbbca14e3c5307ef15e6f258
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/nss.c b/lib/nss.c
index a0cd619..b62c878 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -154,6 +154,16 @@ static const cipher_s cipherlist[] = {
   {"ecdh_anon_3des_sha",         TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
   {"ecdh_anon_aes_128_sha",      TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
   {"ecdh_anon_aes_256_sha",      TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
+#ifdef TLS_RSA_WITH_NULL_SHA256
+  /* new HMAC-SHA256 cipher suites specified in RFC */
+  {"rsa_null_sha_256",                TLS_RSA_WITH_NULL_SHA256},
+  {"rsa_aes_128_cbc_sha_256",         TLS_RSA_WITH_AES_128_CBC_SHA256},
+  {"rsa_aes_256_cbc_sha_256",         TLS_RSA_WITH_AES_256_CBC_SHA256},
+  {"dhe_rsa_aes_128_cbc_sha_256",     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
+  {"dhe_rsa_aes_256_cbc_sha_256",     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
+  {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
+  {"ecdhe_rsa_aes_128_cbc_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
+#endif
 };
 
 static const char* pem_library = "libnsspem.so";
-- 
2.1.0


From f5f9437a4ad184a6ab39ca5b4f835d3c8c76c370 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:14:08 +0100
Subject: [PATCH 20/20] nss: allow to enable/disable new AES GCM cipher-suites

... if built against a new enough version of NSS

Upstream-commit: 67061e3f4ec1c2f3b4bb02bbe2d91ccdeb147c60
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/nss.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/nss.c b/lib/nss.c
index b62c878..7292321 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -164,6 +164,16 @@ static const cipher_s cipherlist[] = {
   {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
   {"ecdhe_rsa_aes_128_cbc_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
 #endif
+#ifdef TLS_RSA_WITH_AES_128_GCM_SHA256
+  /* AES GCM cipher suites in RFC 5288 and RFC 5289 */
+  {"rsa_aes_128_gcm_sha_256",         TLS_RSA_WITH_AES_128_GCM_SHA256},
+  {"dhe_rsa_aes_128_gcm_sha_256",     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+  {"dhe_dss_aes_128_gcm_sha_256",     TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
+  {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+  {"ecdh_ecdsa_aes_128_gcm_sha_256",  TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256},
+  {"ecdhe_rsa_aes_128_gcm_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+  {"ecdh_rsa_aes_128_gcm_sha_256",    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
+#endif
 };
 
 static const char* pem_library = "libnsspem.so";
-- 
2.1.0