Blob Blame History Raw
From f7190e0e76a5813d75ef77496af818c24081af0b 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/19] 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 b568d87..f7d8c5a 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 d2485080cdbe75a51f6953404ad48eafc5ec70c7 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/19] 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 f7d8c5a..c4f54f8 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 d774b12b718a700372de99012e636e20cf28f6ee 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/19] 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 3d31aef..8950004 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -2219,7 +2219,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 37b5e27..57fa6eb 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -678,6 +678,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 80e4cf5..8e548e3 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1625,9 +1625,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 c4f54f8..0ac4538 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 4a0dba7..9e5d3ad 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -1389,19 +1389,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:
@@ -1516,7 +1509,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 297b986..447fe32 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -175,6 +175,9 @@ static const struct LongShort aliases[]= {
   {"$J", "metalink",                 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},
@@ -873,9 +876,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 4014177..9860117 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 14639785030325613953c54fa93b6a7fceeb6b4f 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/19] 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 b350865..74ab3af 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 cf991d603aa27d8feb35f4acb3a88f99bf420dc1 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/19] 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 57fa6eb..b275900 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -678,9 +678,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 545fcd7be34330afa9c9625e16103f0c79d9366a 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/19] 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 8950004..e0bf06c 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -2220,11 +2220,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 a94ff8a00b96341252d7595da914465a37ecbf4e 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/19] 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 2496b3c..ebde78a 100755
--- a/configure
+++ b/configure
@@ -23641,9 +23641,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
@@ -23655,26 +23655,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 5970188..c81c879 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2194,8 +2194,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 03839c3..581b22d 100644
--- a/docs/INTERNALS
+++ b/docs/INTERNALS
@@ -43,7 +43,7 @@ Portability
  openldap     2.0
  MIT krb5 lib 1.2.4
  qsossl       V5R2M0
- NSS          3.12.x
+ NSS          3.14.x
  axTLS        1.2.7
  Heimdal      ?
 
diff --git a/lib/nss.c b/lib/nss.c
index 0ac4538..e607ec2 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 98edf2eb63fcd94b1e99a92d02b0f4e84b767698 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/19] 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 e607ec2..d6e15f4 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 2754542e38955a586ac92a304d2199e6dee8d0af 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/19] 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 d6e15f4..a877d67 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 c3e8b96dd30094e09ed092e12f3390a56733e36c 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/19] 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 ebde78a..8741e21 100755
--- a/configure
+++ b/configure
@@ -23697,18 +23697,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 c81c879..70ef0b7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2211,14 +2211,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 a877d67..df5bff7 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 ac453af9c57cdea802c46b4f723737b1420f8e35 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/19] 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 f9e9869..e750544 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_10_4) || defined(__IPHONE_5_0)
 /* For Apple operating systems: CommonCrypto has the functions we need.
    The library's headers are even backward-compatible with OpenSSL's
@@ -237,7 +235,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;
@@ -245,7 +242,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)
@@ -891,7 +887,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 f08964c3130e95747d86943b3f55ae81e2578e39 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 2 Dec 2013 16:09:12 +0100
Subject: [PATCH 12/19] nss: make sure that 'sslver' is always initialized

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

diff --git a/lib/nss.c b/lib/nss.c
index df5bff7..5872cd9 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1234,7 +1234,6 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
     return CURLE_OK;
 
   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
@@ -1339,7 +1338,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;
@@ -1348,6 +1346,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 1e10b7ca1f63207dfdf8e06f929aad38fbffb0b6 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 7 Feb 2014 20:28:53 +0100
Subject: [PATCH 13/19] --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 124f640..f8c099e 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -199,7 +199,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 34fd60d4cd4c4f18cf7cbeda6ed520c35fd5f4ea Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 17 Feb 2014 16:55:10 +0100
Subject: [PATCH 14/19] 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 74ab3af..3e7f0a0 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 d14741713afa547a0f5e48939130c7397212bd37 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 2 Jul 2014 17:37:43 +0200
Subject: [PATCH 15/19] 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 5872cd9..19e9f0f 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1306,7 +1306,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 dde09a2655ecfa069c2473bab6c980cab73d073e Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 2 Jul 2014 17:49:37 +0200
Subject: [PATCH 16/19] 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 19e9f0f..78a3905 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1309,7 +1309,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 fccb06064d2508fc9cbd72160126e3b590a1d3c2 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:02:03 +0100
Subject: [PATCH 17/19] 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 78a3905..8bd1679 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;
 
@@ -1345,7 +1337,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 */
@@ -1430,16 +1421,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 a4b94e15c8ca412c544292a6ee5f1e4436b83fea Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:10:54 +0100
Subject: [PATCH 18/19] 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 8bd1679..6afa9da 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 a4a39ed8171f321c5b7a88fa658348b553fa1a78 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:14:08 +0100
Subject: [PATCH 19/19] 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 6afa9da..a2e5c79 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