Browse Source

nss: remove support for this TLS library

Closes #11459
Daniel Stenberg 9 months ago
parent
commit
7c8bae0d9c
74 changed files with 117 additions and 3159 deletions
  1. 0 4
      .github/workflows/linux.yml
  2. 0 40
      CMake/FindNSS.cmake
  3. 3 21
      CMakeLists.txt
  4. 5 32
      configure.ac
  5. 1 13
      docs/DEPRECATE.md
  6. 5 5
      docs/FAQ
  7. 1 1
      docs/FEATURES.md
  8. 5 0
      docs/HISTORY.md
  9. 1 1
      docs/HTTP2.md
  10. 1 1
      docs/INSTALL.cmake
  11. 0 1
      docs/INSTALL.md
  12. 0 1
      docs/INTERNALS.md
  13. 0 5
      docs/KNOWN_BUGS
  14. 0 20
      docs/SSLCERTS.md
  15. 0 3
      docs/cmdline-opts/cacert.d
  16. 1 1
      docs/cmdline-opts/cert-status.d
  17. 0 9
      docs/cmdline-opts/cert.d
  18. 2 2
      docs/cmdline-opts/false-start.d
  19. 1 1
      docs/cmdline-opts/page-footer
  20. 2 2
      docs/cmdline-opts/pinnedpubkey.d
  21. 1 1
      docs/cmdline-opts/proxy.d
  22. 2 2
      docs/cmdline-opts/write-out.d
  23. 0 3
      docs/libcurl/libcurl-env.3
  24. 2 2
      docs/libcurl/opts/CURLINFO_CERTINFO.3
  25. 1 1
      docs/libcurl/opts/CURLINFO_SSL_VERIFYRESULT.3
  26. 0 8
      docs/libcurl/opts/CURLOPT_CAINFO.3
  27. 1 1
      docs/libcurl/opts/CURLOPT_CAPATH.3
  28. 3 3
      docs/libcurl/opts/CURLOPT_CERTINFO.3
  29. 2 2
      docs/libcurl/opts/CURLOPT_CRLFILE.3
  30. 1 4
      docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYHOST.3
  31. 2 2
      docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYSTATUS.3
  32. 1 1
      docs/libcurl/opts/CURLOPT_HTTPAUTH.3
  33. 2 2
      docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
  34. 1 4
      docs/libcurl/opts/CURLOPT_PROXY.3
  35. 1 1
      docs/libcurl/opts/CURLOPT_PROXYTYPE.3
  36. 0 3
      docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3
  37. 1 1
      docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3
  38. 5 5
      docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3
  39. 2 2
      docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3
  40. 4 4
      docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3
  41. 0 5
      docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3
  42. 6 6
      docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3
  43. 1 4
      docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3
  44. 4 4
      docs/libcurl/opts/CURLOPT_SSLCERT.3
  45. 0 5
      docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.3
  46. 2 2
      docs/libcurl/opts/CURLOPT_SSL_FALSESTART.3
  47. 2 2
      docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3
  48. 2 2
      docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.3
  49. 0 2
      lib/Makefile.inc
  50. 0 3
      lib/curl_config.h.cmake
  51. 5 6
      lib/curl_des.c
  52. 5 6
      lib/curl_des.h
  53. 4 74
      lib/curl_ntlm_core.c
  54. 0 9
      lib/curl_ntlm_core.h
  55. 7 9
      lib/curl_setup.h
  56. 2 4
      lib/urldata.h
  57. 1 12
      lib/vauth/ntlm.c
  58. 0 2551
      lib/vtls/nss.c
  59. 0 41
      lib/vtls/nssg.h
  60. 1 1
      lib/vtls/sectransp.c
  61. 0 5
      lib/vtls/vtls.c
  62. 0 1
      lib/vtls/vtls_int.h
  63. 6 6
      lib/vtls/x509asn1.c
  64. 3 3
      lib/vtls/x509asn1.h
  65. 0 144
      m4/curl-nss.m4
  66. 0 3
      packages/vms/generate_config_vms_h_curl.com
  67. 1 1
      src/Makefile.am
  68. 0 13
      src/tool_main.c
  69. 0 1
      tests/FILEFORMAT.md
  70. 2 2
      tests/libtest/Makefile.am
  71. 0 10
      tests/libtest/first.c
  72. 0 4
      tests/runtests.pl
  73. 1 1
      tests/unit/Makefile.am
  74. 2 2
      tests/unit/unit1651.c

+ 0 - 4
.github/workflows/linux.yml

@@ -153,10 +153,6 @@ jobs:
           install_steps: intel
           configure: CC=icc --enable-debug --with-openssl
 
-        - name: NSS
-          install_packages: clang libnss3-dev libnghttp2-dev nss-plugin-pem
-          configure: CC=clang CPPFLAGS="-isystem /usr/include/nss" --with-nss --enable-debug --with-nss-deprecated
-
         - name: Slackware-openssl-with-gssapi-gcc
           # These are essentially the same flags used to build the curl Slackware package
           # https://ftpmirror.infania.net/slackware/slackware64-current/source/n/curl/curl.SlackBuild

+ 0 - 40
CMake/FindNSS.cmake

@@ -1,40 +0,0 @@
-#***************************************************************************
-#                                  _   _ ____  _
-#  Project                     ___| | | |  _ \| |
-#                             / __| | | | |_) | |
-#                            | (__| |_| |  _ <| |___
-#                             \___|\___/|_| \_\_____|
-#
-# Copyright (C) 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
-# are also available at https://curl.se/docs/copyright.html.
-#
-# You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# copies of the Software, and permit persons to whom the Software is
-# furnished to do so, under the terms of the COPYING file.
-#
-# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# KIND, either express or implied.
-#
-# SPDX-License-Identifier: curl
-#
-###########################################################################
-if(UNIX)
-  find_package(PkgConfig QUIET)
-  pkg_search_module(PC_NSS nss)
-endif()
-if(NOT PC_NSS_FOUND)
-  return()
-endif()
-
-set(NSS_LIBRARIES ${PC_NSS_LINK_LIBRARIES})
-set(NSS_INCLUDE_DIRS ${PC_NSS_INCLUDE_DIRS})
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(NSS
-    REQUIRED_VARS NSS_LIBRARIES NSS_INCLUDE_DIRS
-    VERSION_VAR PC_NSS_VERSION)
-
-mark_as_advanced(NSS_INCLUDE_DIRS NSS_LIBRARIES)

+ 3 - 21
CMakeLists.txt

@@ -400,11 +400,10 @@ if(WIN32)
 endif()
 cmake_dependent_option(CURL_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
 cmake_dependent_option(CURL_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
-cmake_dependent_option(CURL_USE_NSS "Enable NSS for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
 cmake_dependent_option(CURL_USE_WOLFSSL "enable wolfSSL for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
 
 set(openssl_default ON)
-if(WIN32 OR CURL_USE_SECTRANSP OR CURL_USE_SCHANNEL OR CURL_USE_MBEDTLS OR CURL_USE_NSS OR CURL_USE_WOLFSSL)
+if(WIN32 OR CURL_USE_SECTRANSP OR CURL_USE_SCHANNEL OR CURL_USE_MBEDTLS OR CURL_USE_WOLFSSL)
   set(openssl_default OFF)
 endif()
 cmake_dependent_option(CURL_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default} CURL_ENABLE_SSL OFF)
@@ -416,7 +415,6 @@ count_true(enabled_ssl_options_count
   CURL_USE_OPENSSL
   CURL_USE_MBEDTLS
   CURL_USE_BEARSSL
-  CURL_USE_NSS
   CURL_USE_WOLFSSL
 )
 if(enabled_ssl_options_count GREATER "1")
@@ -512,21 +510,6 @@ if(CURL_USE_WOLFSSL)
   include_directories(${WolfSSL_INCLUDE_DIRS})
 endif()
 
-if(CURL_USE_NSS)
-  find_package(NSS REQUIRED)
-  include_directories(${NSS_INCLUDE_DIRS})
-  list(APPEND CURL_LIBS ${NSS_LIBRARIES})
-  set(SSL_ENABLED ON)
-  set(USE_NSS ON)
-  if(NOT DEFINED HAVE_PK11_CREATEMANAGEDGENERICOBJECT)
-    cmake_push_check_state()
-    set(CMAKE_REQUIRED_INCLUDES ${NSS_INCLUDE_DIRS})
-    set(CMAKE_REQUIRED_LIBRARIES ${NSS_LIBRARIES})
-    check_symbol_exists(PK11_CreateManagedGenericObject "pk11pub.h" HAVE_PK11_CREATEMANAGEDGENERICOBJECT)
-    cmake_pop_check_state()
-  endif()
-endif()
-
 # Keep ZLIB detection after TLS detection,
 # and before calling CheckQuicSupportInOpenSSL.
 
@@ -950,7 +933,7 @@ elseif("${CURL_CA_PATH}" STREQUAL "none")
   unset(CURL_CA_PATH CACHE)
 elseif("${CURL_CA_PATH}" STREQUAL "auto")
   unset(CURL_CA_PATH CACHE)
-  if(NOT CMAKE_CROSSCOMPILING AND NOT USE_NSS)
+  if(NOT CMAKE_CROSSCOMPILING)
     set(CURL_CA_PATH_AUTODETECT TRUE)
   endif()
 else()
@@ -1497,7 +1480,7 @@ _add_if("HTTP2"         USE_NGHTTP2)
 _add_if("HTTP3"         USE_NGTCP2 OR USE_QUICHE)
 _add_if("MultiSSL"      CURL_WITH_MULTI_SSL)
 # TODO wolfSSL only support this from v5.0.0 onwards
-_add_if("HTTPS-proxy"   SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS OR USE_NSS
+_add_if("HTTPS-proxy"   SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS
                         OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR
                         USE_MBEDTLS OR USE_SECTRANSP))
 _add_if("unicode"       ENABLE_UNICODE)
@@ -1555,7 +1538,6 @@ _add_if("OpenSSL"          SSL_ENABLED AND USE_OPENSSL)
 _add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
 _add_if("mbedTLS"          SSL_ENABLED AND USE_MBEDTLS)
 _add_if("BearSSL"          SSL_ENABLED AND USE_BEARSSL)
-_add_if("NSS"              SSL_ENABLED AND USE_NSS)
 _add_if("wolfSSL"          SSL_ENABLED AND USE_WOLFSSL)
 if(_items)
   list(SORT _items)

+ 5 - 32
configure.ac

@@ -147,7 +147,7 @@ AC_SUBST(PKGADD_VENDOR)
 
 dnl
 dnl initialize all the info variables
-    curl_ssl_msg="no      (--with-{openssl,gnutls,nss,mbedtls,wolfssl,schannel,secure-transport,amissl,bearssl,rustls} )"
+    curl_ssl_msg="no      (--with-{openssl,gnutls,mbedtls,wolfssl,schannel,secure-transport,amissl,bearssl,rustls} )"
     curl_ssh_msg="no      (--with-{libssh,libssh2})"
    curl_zlib_msg="no      (--with-zlib)"
  curl_brotli_msg="no      (--with-brotli)"
@@ -298,28 +298,6 @@ AS_HELP_STRING([--with-rustls=PATH],[where to look for rustls, PATH points to th
   fi
 ])
 
-OPT_NSS_AWARE=no
-AC_ARG_WITH(nss-deprecated,dnl
-AS_HELP_STRING([--with-nss-deprecated],[confirm you realize NSS is going away]),
-  if test X"$withval" != Xno; then
-    OPT_NSS_AWARE=$withval
-  fi
-)
-
-OPT_NSS=no
-AC_ARG_WITH(nss,dnl
-AS_HELP_STRING([--with-nss=PATH],[where to look for NSS, PATH points to the installation root]),
-  OPT_NSS=$withval
-  if test X"$withval" != Xno; then
-
-    if test X"$OPT_NSS_AWARE" = "Xno" ; then
-      AC_MSG_ERROR([NSS use must be confirmed using --with-nss-deprecated. NSS support will be dropped from curl in August 2022. See docs/DEPRECATE.md])
-    fi
-
-    [TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }NSS"]
-  fi
-)
-
 TEST_NGHTTPX=nghttpx
 AC_ARG_WITH(test-nghttpx,dnl
 AS_HELP_STRING([--with-test-nghttpx=PATH],[where to find nghttpx for testing]),
@@ -427,7 +405,6 @@ Select from these:
   --with-bearssl
   --with-gnutls
   --with-mbedtls
-  --with-nss
   --with-openssl (also works for BoringSSL and libressl)
   --with-rustls
   --with-schannel
@@ -2091,7 +2068,6 @@ CURL_WITH_MBEDTLS
 CURL_WITH_WOLFSSL
 CURL_WITH_BEARSSL
 CURL_WITH_RUSTLS
-CURL_WITH_NSS
 
 dnl link required libraries for USE_WIN32_CRYPTO or USE_SCHANNEL
 if test "x$USE_WIN32_CRYPTO" = "x1" -o "x$USE_SCHANNEL" = "x1"; then
@@ -2104,11 +2080,11 @@ if test "x$curl_cv_native_windows" = "xyes" &&
   LIBS="-lbcrypt $LIBS"
 fi
 
-case "x$SSL_DISABLED$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$MBEDTLS_ENABLED$WOLFSSL_ENABLED$SCHANNEL_ENABLED$SECURETRANSPORT_ENABLED$BEARSSL_ENABLED$RUSTLS_ENABLED"
+case "x$SSL_DISABLED$OPENSSL_ENABLED$GNUTLS_ENABLED$MBEDTLS_ENABLED$WOLFSSL_ENABLED$SCHANNEL_ENABLED$SECURETRANSPORT_ENABLED$BEARSSL_ENABLED$RUSTLS_ENABLED"
 in
 x)
   AC_MSG_ERROR([TLS not detected, you will not be able to use HTTPS, FTPS, NTLM and more.
-Use --with-openssl, --with-gnutls, --with-wolfssl, --with-mbedtls, --with-nss, --with-schannel, --with-secure-transport, --with-amissl, --with-bearssl or --with-rustls to address this.])
+Use --with-openssl, --with-gnutls, --with-wolfssl, --with-mbedtls, --with-schannel, --with-secure-transport, --with-amissl, --with-bearssl or --with-rustls to address this.])
   ;;
 x1)
   # one SSL backend is enabled
@@ -2121,7 +2097,7 @@ xD)
   ;;
 xD*)
   AC_MSG_ERROR([--without-ssl has been set together with an explicit option to use an ssl library
-(e.g. --with-openssl, --with-gnutls, --with-wolfssl, --with-mbedtls, --with-nss, --with-schannel, --with-secure-transport, --with-amissl, --with-bearssl, --with-rustls).
+(e.g. --with-openssl, --with-gnutls, --with-wolfssl, --with-mbedtls, --with-schannel, --with-secure-transport, --with-amissl, --with-bearssl, --with-rustls).
 Since these are conflicting parameters, verify which is the desired one and drop the other.])
   ;;
 *)
@@ -2504,8 +2480,6 @@ AS_HELP_STRING([--disable-versioned-symbols], [Disable versioned symbols in shar
           versioned_symbols_flavour="OPENSSL_"
         elif test "x$GNUTLS_ENABLED" = "x1"; then
           versioned_symbols_flavour="GNUTLS_"
-        elif test "x$NSS_ENABLED" = "x1"; then
-          versioned_symbols_flavour="NSS_"
         elif test "x$WOLFSSL_ENABLED" = "x1"; then
           versioned_symbols_flavour="WOLFSSL_"
         elif test "x$SCHANNEL_ENABLED" = "x1"; then
@@ -4490,7 +4464,7 @@ use_curl_ntlm_core=no
 if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" -a \
     "x$CURL_DISABLE_NTLM" != "x1"; then
   if test "x$OPENSSL_ENABLED" = "x1" -o "x$MBEDTLS_ENABLED" = "x1" \
-      -o "x$GNUTLS_ENABLED" = "x1" -o "x$NSS_ENABLED" = "x1" \
+      -o "x$GNUTLS_ENABLED" = "x1" \
       -o "x$SECURETRANSPORT_ENABLED" = "x1" \
       -o "x$USE_WIN32_CRYPTO" = "x1" \
       -o "x$WOLFSSL_NTLM" = "x1"; then
@@ -4529,7 +4503,6 @@ dnl if not explicitly turned off, HTTPS-proxy comes with some TLS backends
 if test "x$https_proxy" != "xno"; then
   if test "x$OPENSSL_ENABLED" = "x1" \
       -o "x$GNUTLS_ENABLED" = "x1" \
-      -o "x$NSS_ENABLED" = "x1" \
       -o "x$SECURETRANSPORT_ENABLED" = "x1" \
       -o "x$RUSTLS_ENABLED" = "x1" \
       -o "x$BEARSSL_ENABLED" = "x1" \

+ 1 - 13
docs/DEPRECATE.md

@@ -6,19 +6,6 @@ email the
 as soon as possible and explain to us why this is a problem for you and
 how your use case cannot be satisfied properly using a workaround.
 
-## NSS
-
-We remove support for building curl with the NSS TLS library in August 2023.
-
-- There are few users left who use curl+NSS
-- NSS has few users outside of curl as well (primarily Firefox)
-- NSS is harder than ever to find documentation for
-- NSS was always "best" used with Red Hat Linux when they provided additional
-  features on top of the regular NSS that is not shipped by the vanilla library
-
-Starting in 7.82.0, building curl to use NSS configure requires the additional
-flag `--with-nss-deprecated` in an attempt to highlight these plans.
-
 ## gskit
 
 We remove support for building curl with the gskit TLS library in August 2023.
@@ -69,3 +56,4 @@ curl will remove the support for space-separated names in July 2024.
  - PolarSSL
  - NPN
  - Support for systems without 64 bit data types
+ - NSS

+ 5 - 5
docs/FAQ

@@ -422,10 +422,10 @@ FAQ
   backends.
 
   curl can be built to use one of the following SSL alternatives: OpenSSL,
-  libressl, BoringSSL, AWS-LC, GnuTLS, wolfSSL, NSS, mbedTLS, Secure
-  Transport (native iOS/OS X), Schannel (native Windows), GSKit (native IBM
-  i), BearSSL, or Rustls. They all have their pros and cons, and we try to
-  maintain a comparison of them here: https://curl.se/docs/ssl-compared.html
+  libressl, BoringSSL, AWS-LC, GnuTLS, wolfSSL, mbedTLS, Secure Transport
+  (native iOS/OS X), Schannel (native Windows), GSKit (native IBM i), BearSSL,
+  or Rustls. They all have their pros and cons, and we try to maintain a
+  comparison of them here: https://curl.se/docs/ssl-compared.html
 
   2.4 Does curl support SOCKS (RFC 1928) ?
 
@@ -902,7 +902,7 @@ FAQ
 
   4.9 curl cannot authenticate to a server that requires NTLM?
 
-  NTLM support requires OpenSSL, GnuTLS, mbedTLS, NSS, Secure Transport, or
+  NTLM support requires OpenSSL, GnuTLS, mbedTLS, Secure Transport, or
   Microsoft Windows libraries at build-time to provide this functionality.
 
   4.10 My HTTP request using HEAD, PUT or DELETE does not work

+ 1 - 1
docs/FEATURES.md

@@ -212,7 +212,7 @@
   6. requires c-ares
   7. requires libssh2, libssh or wolfSSH
   8. requires libssh2 or libssh
-  9. requires OpenSSL, GnuTLS, mbedTLS, NSS, Secure Transport or SSPI
+  9. requires OpenSSL, GnuTLS, mbedTLS, Secure Transport or SSPI
      (native Windows)
   10. requires libidn2 or Windows
   11. requires libz, brotli and/or zstd

+ 5 - 0
docs/HISTORY.md

@@ -430,3 +430,8 @@ April: added the cyassl backend (later renamed to WolfSSL)
 
  The curl.se website serves 16,500 GB/month over 462M requests, the
  official docker image has been pulled 4,098,015,431 times.
+
+2023
+----
+
+August: Dropped support for the NSS library

+ 1 - 1
docs/HTTP2.md

@@ -7,7 +7,7 @@ HTTP/2 with curl
 Build prerequisites
 -------------------
   - nghttp2
-  - OpenSSL, libressl, BoringSSL, NSS, GnuTLS, mbedTLS, wolfSSL or Schannel
+  - OpenSSL, libressl, BoringSSL, GnuTLS, mbedTLS, wolfSSL or Schannel
     with a new enough version.
 
 [nghttp2](https://nghttp2.org/)

+ 1 - 1
docs/INSTALL.cmake

@@ -25,7 +25,7 @@ Current flaws in the curl CMake build
 
    - Builds libcurl without large file support
    - Does not support all SSL libraries (only OpenSSL, Schannel,
-     Secure Transport, and mbed TLS, NSS, WolfSSL)
+     Secure Transport, and mbedTLS, WolfSSL)
    - Does not allow different resolver backends (no c-ares build support)
    - No RTMP support built
    - Does not allow build curl and libcurl debug enabled

+ 0 - 1
docs/INSTALL.md

@@ -134,7 +134,6 @@ These options are provided to select the TLS backend to use.
  - BearSSL: `--with-bearssl`
  - GnuTLS: `--with-gnutls`.
  - mbedTLS: `--with-mbedtls`
- - NSS: `--with-nss`
  - OpenSSL: `--with-openssl` (also for BoringSSL, AWS-LC, libressl, and quictls)
  - rustls: `--with-rustls`
  - Schannel: `--with-schannel`

+ 0 - 1
docs/INTERNALS.md

@@ -28,7 +28,6 @@ versions of libs and build tools.
  - OpenLDAP     2.0
  - MIT Kerberos 1.2.4
  - GSKit        V5R3M0
- - NSS          3.14.x
  - Heimdal      ?
  - nghttp2      1.15.0
  - WinSock      2.2 (on Windows 95+ and Windows CE .NET 4.1+)

+ 0 - 5
docs/KNOWN_BUGS

@@ -83,7 +83,6 @@ problems may have been fixed or changed somewhat since this was written.
  12.1 OpenLDAP hangs after returning results
  12.2 LDAP on Windows does authentication wrong?
  12.3 LDAP on Windows does not work
- 12.4 LDAPS with NSS is slow
 
  13. TCP/IP
  13.2 Trying local ports fails on Windows
@@ -504,10 +503,6 @@ problems may have been fixed or changed somewhat since this was written.
 
  https://github.com/curl/curl/issues/4261
 
-12.4 LDAPS with NSS is slow
-
- See https://github.com/curl/curl/issues/5874
-
 13. TCP/IP
 
 13.2 Trying local ports fails on Windows

+ 0 - 20
docs/SSLCERTS.md

@@ -127,26 +127,6 @@ certificate store, will cause SSL to report an error ("certificate verify
 failed") during the handshake and SSL will then refuse further communication
 with that server.
 
-Certificate Verification with NSS
----------------------------------
-
-If libcurl was built with NSS support, then depending on the OS distribution,
-it is probably required to take some additional steps to use the system-wide
-CA cert db. Red Hat ships with an additional module, libnsspem.so, which
-enables NSS to read the OpenSSL PEM CA bundle. On openSUSE you can install
-p11-kit-nss-trust which makes NSS use the system wide CA certificate
-store. NSS also has a new [database
-format](https://wiki.mozilla.org/NSS_Shared_DB).
-
-Starting with version 7.19.7, libcurl automatically adds the `sql:` prefix to
-the certificate database directory (either the set default `/etc/pki/nssdb` or
-the directory configured with the `SSL_DIR` environment variable). To check
-which certificate database format your distribution provides, examine the
-default certificate database location: `/etc/pki/nssdb`; the new certificate
-database format can be identified by the filenames `cert9.db`, `key4.db`,
-`pkcs11.txt`; filenames of older versions are `cert8.db`, `key3.db`,
-`secmod.db`.
-
 Certificate Verification with Schannel and Secure Transport
 -----------------------------------------------------------
 

+ 0 - 3
docs/cmdline-opts/cacert.d

@@ -23,9 +23,6 @@ The windows version of curl will automatically look for a CA certs file named
 'curl-ca-bundle.crt', either in the same directory as curl.exe, or in the
 Current Working Directory, or in any folder along your PATH.
 
-If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module
-(libnsspem.so) needs to be available for this option to work properly.
-
 (iOS and macOS only) If curl is built against Secure Transport, then this
 option is supported for backward compatibility with other SSL engines, but it
 should not be set. If the option is not set, then curl will use the

+ 1 - 1
docs/cmdline-opts/cert-status.d

@@ -16,4 +16,4 @@ If this option is enabled and the server sends an invalid (e.g. expired)
 response, if the response suggests that the server certificate has been
 revoked, or no response at all is received, the verification fails.
 
-This is currently only implemented in the OpenSSL, GnuTLS and NSS backends.
+This is currently only implemented in the OpenSSL and GnuTLS backends.

+ 0 - 9
docs/cmdline-opts/cert.d

@@ -24,15 +24,6 @@ as "\\:" so that it is not recognized as the password delimiter. Similarly, you
 must escape the character "\\" as "\\\\" so that it is not recognized as an
 escape character.
 
-If curl is built against the NSS SSL library then this option can tell
-curl the nickname of the certificate to use within the NSS database defined
-by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
-NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
-loaded.
-
-If you provide a path relative to the current directory, you must prefix the
-path with "./" in order to avoid confusion with an NSS database nickname.
-
 If curl is built against OpenSSL library, and the engine pkcs11 is available,
 then a PKCS#11 URI (RFC 7512) can be used to specify a certificate located in
 a PKCS#11 device. A string beginning with "pkcs11:" will be interpreted as a

+ 2 - 2
docs/cmdline-opts/false-start.d

@@ -14,5 +14,5 @@ where a TLS client will start sending application data before verifying the
 server's Finished message, thus saving a round trip when performing a full
 handshake.
 
-This is currently only implemented in the NSS and Secure Transport (on iOS 7.0
-or later, or OS X 10.9 or later) backends.
+This is currently only implemented in the Secure Transport (on iOS 7.0 or
+later, or OS X 10.9 or later) backend.

+ 1 - 1
docs/cmdline-opts/page-footer

@@ -82,7 +82,7 @@ If you set this environment variable to a file name, curl will store TLS
 secrets from its connections in that file when invoked to enable you to
 analyze the TLS traffic in real time using network analyzing tools such as
 Wireshark. This works with the following TLS backends: OpenSSL, libressl,
-BoringSSL, GnuTLS, NSS and wolfSSL.
+BoringSSL, GnuTLS and wolfSSL.
 .IP "USERPROFILE <dir>"
 On Windows, this variable is used when trying to find the home directory. If
 the other, primary, variable are all unset. If set, curl will use the path

+ 2 - 2
docs/cmdline-opts/pinnedpubkey.d

@@ -25,13 +25,13 @@ PEM/DER support:
 
 7.39.0: OpenSSL, GnuTLS and GSKit
 
-7.43.0: NSS and wolfSSL
+7.43.0: wolfSSL
 
 7.47.0: mbedtls
 
 sha256 support:
 
-7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL
+7.44.0: OpenSSL, GnuTLS and wolfSSL
 
 7.47.0: mbedtls
 

+ 1 - 1
docs/cmdline-opts/proxy.d

@@ -21,7 +21,7 @@ Unix domain sockets are supported for socks proxy. Set localhost for the host
 part. e.g. socks5h://localhost/path/to/socket.sock
 
 HTTPS proxy support via https:// protocol prefix was added in 7.52.0 for
-OpenSSL, GnuTLS and NSS. Since 7.87.0, it also works for BearSSL, mbedTLS,
+OpenSSL and GnuTLS. Since 7.87.0, it also works for BearSSL, mbedTLS,
 rustls, Schannel, Secure Transport and wolfSSL.
 
 Unrecognized and unsupported proxy protocols cause an error since 7.52.0.

+ 2 - 2
docs/cmdline-opts/write-out.d

@@ -41,7 +41,7 @@ The variables available are:
 .TP 15
 .B certs
 Output the certificate chain with details. Supported only by the OpenSSL,
-GnuTLS, Schannel, NSS, GSKit and Secure Transport backends. (Added in 7.88.0)
+GnuTLS, Schannel, GSKit and Secure Transport backends. (Added in 7.88.0)
 .TP
 .B content_type
 The Content-Type of the requested document, if there was any.
@@ -97,7 +97,7 @@ The http method used in the most recent HTTP request. (Added in 7.72.0)
 .TP
 .B num_certs
 Number of server certificates received in the TLS handshake. Supported only by
-the OpenSSL, GnuTLS, Schannel, NSS, GSKit and Secure Transport backends. (Added
+the OpenSSL, GnuTLS, Schannel, GSKit and Secure Transport backends. (Added
 in 7.88.0)
 .TP
 .B num_connects

+ 0 - 3
docs/libcurl/libcurl-env.3

@@ -74,9 +74,6 @@ When set and libcurl runs with a SSL backend that supports this feature,
 libcurl will save SSL secrets into the given file name. Using those SSL
 secrets, other tools (such as Wireshark) can decrypt the SSL communication and
 analyze/view the traffic.
-.IP SSL_DIR
-When libcurl runs with the NSS backends for TLS features, this variable is
-used to find the directory for NSS PKI database instead of the built-in.
 .IP USER
 User name to use when invoking the \fIntlm-wb\fP tool, if \fINTLMUSER\fP and
 \fILOGNAME\fP were not set.

+ 2 - 2
docs/libcurl/opts/CURLINFO_CERTINFO.3

@@ -75,8 +75,8 @@ if(curl) {
 }
 .fi
 .SH AVAILABILITY
-This option is only working in libcurl built with OpenSSL, NSS, Schannel, GSKit
-or Secure Transport support. Schannel support added in 7.50.0. Secure Transport
+This option is only working in libcurl built with OpenSSL, Schannel, GSKit or
+Secure Transport support. Schannel support added in 7.50.0. Secure Transport
 support added in 7.79.0.
 
 Added in 7.19.1

+ 1 - 1
docs/libcurl/opts/CURLINFO_SSL_VERIFYRESULT.3

@@ -55,7 +55,7 @@ if(curl) {
 }
 .fi
 .SH AVAILABILITY
-Added in 7.5. Only set by the OpenSSL/libressl/boringssl, NSS and GnuTLS backends.
+Added in 7.5. Only set by the OpenSSL/libressl/boringssl and GnuTLS backends.
 .SH RETURN VALUE
 Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
 .SH "SEE ALSO"

+ 0 - 8
docs/libcurl/opts/CURLOPT_CAINFO.3

@@ -42,14 +42,6 @@ accessible file.
 This option is by default set to the system path where libcurl's CA
 certificate bundle is assumed to be stored, as established at build time.
 
-If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module
-(libnsspem.so) needs to be available for this option to work properly.
-Starting with curl 7.55.0, if both \fICURLOPT_CAINFO(3)\fP and
-\fICURLOPT_CAPATH(3)\fP are unset, NSS-linked libcurl tries to load
-libnssckbi.so, which contains a more comprehensive set of trust information
-than supported by nss-pem, because libnssckbi.so also includes information
-about distrusted certificates.
-
 (iOS and macOS) When curl uses Secure Transport this option is supported. If
 the option is not set, then curl will use the certificates in the system and
 user Keychain to verify the peer.

+ 1 - 1
docs/libcurl/opts/CURLOPT_CAPATH.3

@@ -61,7 +61,7 @@ if(curl) {
 .fi
 .SH AVAILABILITY
 This option is supported by the OpenSSL, GnuTLS and mbedTLS (since 7.56.0)
-backends. The NSS backend provides the option only for backward compatibility.
+backends.
 .SH RETURN VALUE
 CURLE_OK if supported; or an error such as:
 

+ 3 - 3
docs/libcurl/opts/CURLOPT_CERTINFO.3

@@ -74,9 +74,9 @@ if(curl) {
 }
 .fi
 .SH AVAILABILITY
-This option is supported by the OpenSSL, GnuTLS, Schannel, NSS, GSKit and
-Secure Transport backends. Schannel support added in 7.50.0. Secure Transport
-support added in 7.79.0.
+This option is supported by the OpenSSL, GnuTLS, Schannel, GSKit and Secure
+Transport backends. Schannel support added in 7.50.0. Secure Transport support
+added in 7.79.0.
 .SH RETURN VALUE
 Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
 .SH "SEE ALSO"

+ 2 - 2
docs/libcurl/opts/CURLOPT_CRLFILE.3

@@ -36,8 +36,8 @@ Pass a char * to a null-terminated string naming a \fIfile\fP with the
 concatenation of CRL (in PEM format) to use in the certificate validation that
 occurs during the SSL exchange.
 
-When curl is built to use NSS or GnuTLS, there is no way to influence the use
-of CRL passed to help in the verification process.
+When curl is built to use GnuTLS, there is no way to influence the use of CRL
+passed to help in the verification process.
 
 When libcurl is built with OpenSSL support, X509_V_FLAG_CRL_CHECK and
 X509_V_FLAG_CRL_CHECK_ALL are both set, requiring CRL check against all the

+ 1 - 4
docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYHOST.3

@@ -55,10 +55,7 @@ When the \fIverify\fP value is set to 0L, the connection succeeds regardless of
 the names used in the certificate. Use that ability with caution!
 
 See also \fICURLOPT_DOH_SSL_VERIFYPEER(3)\fP to verify the digital signature
-of the DoH server certificate.  If libcurl is built against NSS and
-\fICURLOPT_DOH_SSL_VERIFYPEER(3)\fP is zero,
-\fICURLOPT_DOH_SSL_VERIFYHOST(3)\fP is also set to zero and cannot be
-overridden.
+of the DoH server certificate.
 .SH DEFAULT
 2
 .SH PROTOCOLS

+ 2 - 2
docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYSTATUS.3

@@ -63,8 +63,8 @@ if(curl) {
 }
 .fi
 .SH AVAILABILITY
-Added in 7.76.0. This option is currently only supported by the OpenSSL, GnuTLS
-and NSS TLS backends.
+Added in 7.76.0. This option is currently only supported by the OpenSSL, and
+GnuTLS TLS backends.
 .SH RETURN VALUE
 Returns CURLE_OK if OCSP stapling is supported by the SSL backend, otherwise
 returns CURLE_NOT_BUILT_IN.

+ 1 - 1
docs/libcurl/opts/CURLOPT_HTTPAUTH.3

@@ -73,7 +73,7 @@ HTTP NTLM authentication. A proprietary protocol invented and used by
 Microsoft. It uses a challenge-response and hash concept similar to Digest, to
 prevent the password from being eavesdropped.
 
-You need to build libcurl with either OpenSSL, GnuTLS or NSS support for this
+You need to build libcurl with either OpenSSL or GnuTLS support for this
 option to work, or build libcurl on Windows with SSPI support.
 .IP CURLAUTH_NTLM_WB
 NTLM delegating to winbind helper. Authentication is performed by a separate

+ 2 - 2
docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3

@@ -104,7 +104,7 @@ PEM/DER support:
 
   7.39.0-7.48.0,7.58.1+: GSKit
 
-  7.43.0: NSS and wolfSSL
+  7.43.0: wolfSSL
 
   7.47.0: mbedTLS
 
@@ -114,7 +114,7 @@ PEM/DER support:
 
 sha256 support:
 
-  7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL
+  7.44.0: OpenSSL, GnuTLS and wolfSSL
 
   7.47.0: mbedTLS
 

+ 1 - 4
docs/libcurl/opts/CURLOPT_PROXY.3

@@ -48,7 +48,7 @@ proxy is used.
 .IP http://
 HTTP Proxy. Default when no scheme or proxy type is specified.
 .IP https://
-HTTPS Proxy. (Added in 7.52.0 for OpenSSL, GnuTLS and NSS. Since 7.87.0, it
+HTTPS Proxy. (Added in 7.52.0 for OpenSSL and GnuTLS Since 7.87.0, it
 also works for BearSSL, mbedTLS, rustls, Schannel, Secure Transport and
 wolfSSL.)
 
@@ -123,9 +123,6 @@ Since 7.21.7 the proxy string supports the socks protocols as "schemes".
 
 Since 7.50.2, unsupported schemes in proxy strings cause libcurl to return
 error.
-
-curl built to use NSS cannot connect to an HTTPS server over a unix domain
-socket.
 .SH RETURN VALUE
 Returns CURLE_OK if proxies are supported, CURLE_UNKNOWN_OPTION if not, or
 CURLE_OUT_OF_MEMORY if there was insufficient heap space.

+ 1 - 1
docs/libcurl/opts/CURLOPT_PROXYTYPE.3

@@ -38,7 +38,7 @@ Pass one of the values below to set the type of the proxy.
 .IP CURLPROXY_HTTP
 HTTP Proxy. Default.
 .IP CURLPROXY_HTTPS
-HTTPS Proxy using HTTP/1. (Added in 7.52.0 for OpenSSL, GnuTLS and NSS. Since
+HTTPS Proxy using HTTP/1. (Added in 7.52.0 for OpenSSL and GnuTLS. Since
 7.87.0, it also works for BearSSL, mbedTLS, rustls, Schannel, Secure Transport
 and wolfSSL.)
 .IP CURLPROXY_HTTPS2

+ 0 - 3
docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3

@@ -44,9 +44,6 @@ accessible file.
 This option is by default set to the system path where libcurl's CA
 certificate bundle is assumed to be stored, as established at build time.
 
-If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module
-(libnsspem.so) needs to be available for this option to work properly.
-
 (iOS and macOS only) If curl is built against Secure Transport, then this
 option is supported for backward compatibility with other SSL engines, but it
 should not be set. If the option is not set, then curl will use the

+ 1 - 1
docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3

@@ -62,7 +62,7 @@ if(curl) {
 Added in 7.52.0
 
 This option is supported by the OpenSSL, GnuTLS, and mbedTLS (since 7.56.0)
-backends. The NSS backend provides the option only for backward compatibility.
+backends.
 .SH RETURN VALUE
 CURLE_OK if supported; or an error such as:
 

+ 5 - 5
docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3

@@ -38,11 +38,11 @@ Pass a char * to a null-terminated string naming a \fIfile\fP with the
 concatenation of CRL (in PEM format) to use in the certificate validation that
 occurs during the SSL exchange.
 
-When curl is built to use NSS or GnuTLS, there is no way to influence the use
-of CRL passed to help in the verification process. When libcurl is built with
-OpenSSL support, X509_V_FLAG_CRL_CHECK and X509_V_FLAG_CRL_CHECK_ALL are both
-set, requiring CRL check against all the elements of the certificate chain if
-a CRL file is passed.
+When curl is built to use GnuTLS, there is no way to influence the use of CRL
+passed to help in the verification process. When libcurl is built with OpenSSL
+support, X509_V_FLAG_CRL_CHECK and X509_V_FLAG_CRL_CHECK_ALL are both set,
+requiring CRL check against all the elements of the certificate chain if a CRL
+file is passed.
 
 This option makes sense only when used in combination with the
 \fICURLOPT_PROXY_SSL_VERIFYPEER(3)\fP option.

+ 2 - 2
docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3

@@ -98,11 +98,11 @@ footer:
 .SH AVAILABILITY
 PEM/DER support:
 
-  7.52.0: GSKit, GnuTLS, NSS, OpenSSL, mbedTLS, wolfSSL
+  7.52.0: GSKit, GnuTLS, OpenSSL, mbedTLS, wolfSSL
 
 sha256 support:
 
-  7.52.0: GnuTLS, NSS, OpenSSL, mbedTLS, wolfSSL
+  7.52.0: GnuTLS, OpenSSL, mbedTLS, wolfSSL
 
 Other SSL backends not supported.
 .SH RETURN VALUE

+ 4 - 4
docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3

@@ -39,10 +39,10 @@ the file name of your client certificate used to connect to the HTTPS proxy.
 The default format is "P12" on Secure Transport and "PEM" on other engines,
 and can be changed with \fICURLOPT_PROXY_SSLCERTTYPE(3)\fP.
 
-With NSS or Secure Transport, this can also be the nickname of the certificate
-you wish to authenticate with as it is named in the security database. If you
-want to use a file from the current directory, please precede it with "./"
-prefix, in order to avoid confusion with a nickname.
+With Secure Transport, this can also be the nickname of the certificate you
+wish to authenticate with as it is named in the security database. If you want
+to use a file from the current directory, please precede it with "./" prefix,
+in order to avoid confusion with a nickname.
 
 When using a client certificate, you most likely also need to provide a
 private key with \fICURLOPT_PROXY_SSLKEY(3)\fP.

+ 0 - 5
docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3

@@ -43,11 +43,6 @@ For OpenSSL and GnuTLS valid examples of cipher lists include \fBRC4-SHA\fP,
 \fBSHA1+DES\fP, \fBTLSv1\fP and \fBDEFAULT\fP. The default list is normally
 set when you compile OpenSSL.
 
-For NSS, valid examples of cipher lists include \fBrsa_rc4_128_md5\fP,
-\fBrsa_aes_128_sha\fP, etc. With NSS you do not add/remove ciphers. If one uses
-this option then all known ciphers are disabled and only those passed in are
-enabled.
-
 For WolfSSL, valid examples of cipher lists include \fBECDHE-RSA-RC4-SHA\fP,
 \fBAES256-SHA:AES256-SHA256\fP, etc.
 

+ 6 - 6
docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3

@@ -37,12 +37,12 @@ Pass a long with a bitmask to tell libcurl about specific SSL
 behaviors. Available bits:
 .IP CURLSSLOPT_ALLOW_BEAST
 Tells libcurl to not attempt to use any workarounds for a security flaw in the
-SSL3 and TLS1.0 protocols.  If this option is not used or this bit is set to 0,
-the SSL layer libcurl uses may use a work-around for this flaw although it
-might cause interoperability problems with some (older) SSL
-implementations. WARNING: avoiding this work-around lessens the security, and
-by setting this option to 1 you ask for exactly that.  This option is only
-supported for Secure Transport, NSS and OpenSSL.
+SSL3 and TLS1.0 protocols.  If this option is not used or this bit is set to
+0, the SSL layer libcurl uses may use a work-around for this flaw although it
+might cause interoperability problems with some (older) SSL implementations.
+WARNING: avoiding this work-around lessens the security, and by setting this
+option to 1 you ask for exactly that. This option is only supported for
+Secure Transport and OpenSSL.
 .IP CURLSSLOPT_NO_REVOKE
 Tells libcurl to disable certificate revocation checks for those SSL backends
 where such behavior is present. This option is only supported for Schannel

+ 1 - 4
docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3

@@ -61,10 +61,7 @@ When the \fIverify\fP value is 0L, the connection succeeds regardless of the
 names used in the certificate. Use that ability with caution!
 
 See also \fICURLOPT_PROXY_SSL_VERIFYPEER(3)\fP to verify the digital signature
-of the proxy certificate.  If libcurl is built against NSS and
-\fICURLOPT_PROXY_SSL_VERIFYPEER(3)\fP is zero,
-\fICURLOPT_PROXY_SSL_VERIFYHOST(3)\fP is also set to zero and cannot be
-overridden.
+of the proxy certificate.
 .SH DEFAULT
 2
 .SH PROTOCOLS

+ 4 - 4
docs/libcurl/opts/CURLOPT_SSLCERT.3

@@ -37,10 +37,10 @@ the file name of your client certificate. The default format is "P12" on
 Secure Transport and "PEM" on other engines, and can be changed with
 \fICURLOPT_SSLCERTTYPE(3)\fP.
 
-With NSS or Secure Transport, this can also be the nickname of the certificate
-you wish to authenticate with as it is named in the security database. If you
-want to use a file from the current directory, please precede it with "./"
-prefix, in order to avoid confusion with a nickname.
+With Secure Transport, this can also be the nickname of the certificate you
+wish to authenticate with as it is named in the security database. If you want
+to use a file from the current directory, please precede it with "./" prefix,
+in order to avoid confusion with a nickname.
 
 (Schannel only) Client certificates can be specified by a path expression to a
 certificate store. (You can import \fIPFX\fP to a store first). You can use

+ 0 - 5
docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.3

@@ -42,11 +42,6 @@ For OpenSSL and GnuTLS valid examples of cipher lists include \fBRC4-SHA\fP,
 \fBSHA1+DES\fP, \fBTLSv1\fP and \fBDEFAULT\fP. The default list is normally
 set when you compile OpenSSL.
 
-For NSS, valid examples of cipher lists include \fBrsa_rc4_128_md5\fP,
-\fBrsa_aes_128_sha\fP, etc. With NSS you do not add/remove ciphers. If one uses
-this option then all known ciphers are disabled and only those passed in are
-enabled.
-
 For WolfSSL, valid examples of cipher lists include \fBECDHE-RSA-RC4-SHA\fP,
 \fBAES256-SHA:AES256-SHA256\fP, etc.
 

+ 2 - 2
docs/libcurl/opts/CURLOPT_SSL_FALSESTART.3

@@ -52,8 +52,8 @@ if(curl) {
 }
 .fi
 .SH AVAILABILITY
-Added in 7.42.0. This option is currently only supported by the NSS and
-Secure Transport (on iOS 7.0 or later, or OS X 10.9 or later) TLS backends.
+Added in 7.42.0. This option is currently only supported by the Secure
+Transport (on iOS 7.0 or later, or OS X 10.9 or later) TLS backend.
 .SH RETURN VALUE
 Returns CURLE_OK if false start is supported by the SSL backend, otherwise
 returns CURLE_NOT_BUILT_IN.

+ 2 - 2
docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3

@@ -40,8 +40,8 @@ SSL3 and TLS1.0 protocols.  If this option is not used or this bit is set to 0,
 the SSL layer libcurl uses may use a work-around for this flaw although it
 might cause interoperability problems with some (older) SSL
 implementations. WARNING: avoiding this work-around lessens the security, and
-by setting this option to 1 you ask for exactly that.  This option is only
-supported for Secure Transport, NSS and OpenSSL.
+by setting this option to 1 you ask for exactly that. This option is only
+supported for Secure Transport and OpenSSL.
 .IP CURLSSLOPT_NO_REVOKE
 Tells libcurl to disable certificate revocation checks for those SSL backends
 where such behavior is present. This option is only supported for Schannel

+ 2 - 2
docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.3

@@ -55,8 +55,8 @@ if(curl) {
 }
 .fi
 .SH AVAILABILITY
-Added in 7.41.0. This option is currently only supported by the OpenSSL, GnuTLS
-and NSS TLS backends.
+Added in 7.41.0. This option is currently only supported by the OpenSSL and
+GnuTLS TLS backends.
 .SH RETURN VALUE
 Returns CURLE_OK if OCSP stapling is supported by the SSL backend, otherwise
 returns CURLE_NOT_BUILT_IN.

+ 0 - 2
lib/Makefile.inc

@@ -50,7 +50,6 @@ LIB_VTLS_CFILES =           \
   vtls/keylog.c             \
   vtls/mbedtls.c            \
   vtls/mbedtls_threadlock.c \
-  vtls/nss.c                \
   vtls/openssl.c            \
   vtls/rustls.c             \
   vtls/schannel.c           \
@@ -68,7 +67,6 @@ LIB_VTLS_HFILES =           \
   vtls/keylog.h             \
   vtls/mbedtls.h            \
   vtls/mbedtls_threadlock.h \
-  vtls/nssg.h               \
   vtls/openssl.h            \
   vtls/rustls.h             \
   vtls/schannel.h           \

+ 0 - 3
lib/curl_config.h.cmake

@@ -688,9 +688,6 @@ ${SIZEOF_TIME_T_CODE}
 /* If you want to build curl with the built-in manual */
 #cmakedefine USE_MANUAL 1
 
-/* if NSS is enabled */
-#cmakedefine USE_NSS 1
-
 /* if you have the PK11_CreateManagedGenericObject function */
 #cmakedefine HAVE_PK11_CREATEMANAGEDGENERICOBJECT 1
 

+ 5 - 6
lib/curl_des.c

@@ -24,12 +24,11 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) && \
-    (defined(USE_GNUTLS) || \
-     defined(USE_NSS) || \
-     defined(USE_SECTRANSP) || \
-     defined(USE_OS400CRYPTO) || \
-     defined(USE_WIN32_CRYPTO))
+#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) &&     \
+  (defined(USE_GNUTLS) ||                                       \
+   defined(USE_SECTRANSP) ||                                    \
+   defined(USE_OS400CRYPTO) ||                                  \
+   defined(USE_WIN32_CRYPTO))
 
 #include "curl_des.h"
 

+ 5 - 6
lib/curl_des.h

@@ -26,12 +26,11 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) && \
-    (defined(USE_GNUTLS) || \
-     defined(USE_NSS) || \
-     defined(USE_SECTRANSP) || \
-     defined(USE_OS400CRYPTO) || \
-     defined(USE_WIN32_CRYPTO))
+#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) &&     \
+  (defined(USE_GNUTLS) ||                                       \
+   defined(USE_SECTRANSP) ||                                    \
+   defined(USE_OS400CRYPTO) ||                                  \
+   defined(USE_WIN32_CRYPTO))
 
 /* Applies odd parity to the given byte array */
 void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);

+ 4 - 74
lib/curl_ntlm_core.c

@@ -38,7 +38,7 @@
    1. USE_OPENSSL
    2. USE_WOLFSSL
    3. USE_GNUTLS
-   4. USE_NSS
+   4. -
    5. USE_MBEDTLS
    6. USE_SECTRANSP
    7. USE_OS400CRYPTO
@@ -47,7 +47,7 @@
    This ensures that:
    - the same SSL branch gets activated throughout this source
      file even if multiple backends are enabled at the same time.
-   - OpenSSL and NSS have higher priority than Windows Crypt, due
+   - OpenSSL has higher priority than Windows Crypt, due
      to issues with the latter supporting NTLM2Session responses
      in NTLM type-3 messages.
  */
@@ -96,12 +96,6 @@
 
 #  include <nettle/des.h>
 
-#elif defined(USE_NSS)
-
-#  include <nss.h>
-#  include <pk11pub.h>
-#  include <hasht.h>
-
 #elif defined(USE_MBEDTLS)
 
 #  include <mbedtls/des.h>
@@ -188,70 +182,6 @@ static void setup_des_key(const unsigned char *key_56,
   des_set_key(des, (const uint8_t *) key);
 }
 
-#elif defined(USE_NSS)
-
-/*
- * encrypt_des() expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of
- * data, using the expanded key. IN should point to 64 bits of source data,
- * OUT to a 64 bit output buffer.
- */
-static bool encrypt_des(const unsigned char *in, unsigned char *out,
-                        const unsigned char *key_56)
-{
-  const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
-  char key[8];                                /* expanded 64 bit key */
-  SECItem key_item;
-  PK11SymKey *symkey = NULL;
-  SECItem *param = NULL;
-  PK11Context *ctx = NULL;
-  int out_len;                                /* not used, required by NSS */
-  bool rv = FALSE;
-
-  /* use internal slot for DES encryption (requires NSS to be initialized) */
-  PK11SlotInfo *slot = PK11_GetInternalKeySlot();
-  if(!slot)
-    return FALSE;
-
-  /* Expand the 56-bit key to 64-bits */
-  extend_key_56_to_64(key_56, key);
-
-  /* Set the key parity to odd */
-  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
-
-  /* Import the key */
-  key_item.data = (unsigned char *)key;
-  key_item.len = sizeof(key);
-  symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
-                             &key_item, NULL);
-  if(!symkey)
-    goto fail;
-
-  /* Create the DES encryption context */
-  param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
-  if(!param)
-    goto fail;
-  ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
-  if(!ctx)
-    goto fail;
-
-  /* Perform the encryption */
-  if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
-                                 (unsigned char *)in, /* inbuflen */ 8)
-      && SECSuccess == PK11_Finalize(ctx))
-    rv = /* all OK */ TRUE;
-
-fail:
-  /* cleanup */
-  if(ctx)
-    PK11_DestroyContext(ctx, PR_TRUE);
-  if(symkey)
-    PK11_FreeSymKey(symkey);
-  if(param)
-    SECITEM_FreeItem(param, PR_TRUE);
-  PK11_FreeSlot(slot);
-  return rv;
-}
-
 #elif defined(USE_MBEDTLS)
 
 static bool encrypt_des(const unsigned char *in, unsigned char *out,
@@ -402,7 +332,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
   des_encrypt(&des, 8, results + 8, plaintext);
   setup_des_key(keys + 14, &des);
   des_encrypt(&des, 8, results + 16, plaintext);
-#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
+#elif defined(USE_MBEDTLS) || defined(USE_SECTRANSP)            \
   || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
   encrypt_des(plaintext, results, keys);
   encrypt_des(plaintext, results + 8, keys + 7);
@@ -444,7 +374,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(const char *password,
     des_encrypt(&des, 8, lmbuffer, magic);
     setup_des_key(pw + 7, &des);
     des_encrypt(&des, 8, lmbuffer + 8, magic);
-#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
+#elif defined(USE_MBEDTLS) || defined(USE_SECTRANSP)            \
   || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
     encrypt_des(magic, lmbuffer, pw);
     encrypt_des(magic, lmbuffer + 8, pw + 7);

+ 0 - 9
lib/curl_ntlm_core.h

@@ -28,15 +28,6 @@
 
 #if defined(USE_CURL_NTLM_CORE)
 
-/* If NSS is the first available SSL backend (see order in curl_ntlm_core.c)
-   then it must be initialized to be used by NTLM. */
-#if !defined(USE_OPENSSL) && \
-    !defined(USE_WOLFSSL) && \
-    !defined(USE_GNUTLS) && \
-    defined(USE_NSS)
-#define NTLM_NEEDS_NSS_INIT
-#endif
-
 #if defined(USE_OPENSSL)
 #  include <openssl/ssl.h>
 #elif defined(USE_WOLFSSL)

+ 7 - 9
lib/curl_setup.h

@@ -645,11 +645,9 @@
 
 #define LIBIDN_REQUIRED_VERSION "0.4.1"
 
-#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
-    defined(USE_MBEDTLS) || \
-    defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \
-    defined(USE_SECTRANSP) || defined(USE_GSKIT) || \
-    defined(USE_BEARSSL) || defined(USE_RUSTLS)
+#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
+  defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
+  defined(USE_GSKIT) || defined(USE_BEARSSL) || defined(USE_RUSTLS)
 #define USE_SSL    /* SSL support has been enabled */
 #endif
 
@@ -667,10 +665,10 @@
 
 /* Single point where USE_NTLM definition might be defined */
 #if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(CURL_DISABLE_NTLM)
-#  if defined(USE_OPENSSL) || defined(USE_MBEDTLS) ||                       \
-      defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) ||  \
-      defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) ||              \
-      (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
+#  if defined(USE_OPENSSL) || defined(USE_MBEDTLS) ||                   \
+  defined(USE_GNUTLS) || defined(USE_SECTRANSP) ||                      \
+  defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) ||              \
+  (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
 #    define USE_CURL_NTLM_CORE
 #  endif
 #  if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI)

+ 2 - 4
lib/urldata.h

@@ -1116,10 +1116,8 @@ struct PureInfo {
   int conn_local_port;
   const char *conn_scheme;
   unsigned int conn_protocol;
-  struct curl_certinfo certs; /* info about the certs, only populated in
-                                 OpenSSL, GnuTLS, Schannel, NSS and GSKit
-                                 builds. Asked for with CURLOPT_CERTINFO
-                                 / CURLINFO_CERTINFO */
+  struct curl_certinfo certs; /* info about the certs. Asked for with
+                                 CURLOPT_CERTINFO / CURLINFO_CERTINFO */
   CURLproxycode pxcode;
   BIT(timecond);  /* set to TRUE if the time condition didn't match, which
                      thus made the document NOT get fetched */

+ 1 - 12
lib/vauth/ntlm.c

@@ -45,12 +45,6 @@
 #include "rand.h"
 #include "vtls/vtls.h"
 
-/* SSL backend-specific #if branches in this file must be kept in the order
-   documented in curl_ntlm_core. */
-#if defined(NTLM_NEEDS_NSS_INIT)
-#include "vtls/nssg.h" /* for Curl_nss_force_init() */
-#endif
-
 #define BUILDING_CURL_NTLM_MSGS_C
 #include "vauth/vauth.h"
 #include "vauth/ntlm.h"
@@ -274,12 +268,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
   const unsigned char *type2 = Curl_bufref_ptr(type2ref);
   size_t type2len = Curl_bufref_len(type2ref);
 
-#if defined(NTLM_NEEDS_NSS_INIT)
-  /* Make sure the crypto backend is initialized */
-  result = Curl_nss_force_init(data);
-  if(result)
-    return result;
-#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
   (void)data;
 #endif
 

+ 0 - 2551
lib/vtls/nss.c

@@ -1,2551 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 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
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
-
-/*
- * Source file for all NSS-specific code for the TLS/SSL layer. No code
- * but vtls.c should ever call or use these functions.
- */
-
-#include "curl_setup.h"
-
-#ifdef USE_NSS
-
-#include "urldata.h"
-#include "sendf.h"
-#include "formdata.h" /* for the boundary function */
-#include "url.h" /* for the ssl config check function */
-#include "connect.h"
-#include "strcase.h"
-#include "select.h"
-#include "vtls.h"
-#include "vtls_int.h"
-#include "llist.h"
-#include "multiif.h"
-#include "curl_printf.h"
-#include "nssg.h"
-#include <nspr.h>
-#include <nss.h>
-#include <ssl.h>
-#include <sslerr.h>
-#include <secerr.h>
-#include <secmod.h>
-#include <sslproto.h>
-#include <prtypes.h>
-#include <pk11pub.h>
-#include <prio.h>
-#include <secitem.h>
-#include <secport.h>
-#include <certdb.h>
-#include <base64.h>
-#include <cert.h>
-#include <prerror.h>
-#include <keyhi.h>         /* for SECKEY_DestroyPublicKey() */
-#include <private/pprio.h> /* for PR_ImportTCPSocket */
-
-#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH)
-
-#if NSSVERNUM >= 0x030f00 /* 3.15.0 */
-#include <ocsp.h>
-#endif
-
-#include "warnless.h"
-#include "x509asn1.h"
-
-/* The last #include files should be: */
-#include "curl_memory.h"
-#include "memdebug.h"
-
-#define SSL_DIR "/etc/pki/nssdb"
-
-/* enough to fit the string "PEM Token #[0|1]" */
-#define SLOTSIZE 13
-
-struct nss_ssl_backend_data {
-  PRFileDesc *handle;
-  char *client_nickname;
-  struct Curl_easy *data;
-  struct Curl_llist obj_list;
-  PK11GenericObject *obj_clicert;
-};
-
-static PRLock *nss_initlock = NULL;
-static PRLock *nss_crllock = NULL;
-static PRLock *nss_findslot_lock = NULL;
-static PRLock *nss_trustload_lock = NULL;
-static struct Curl_llist nss_crl_list;
-static NSSInitContext *nss_context = NULL;
-static volatile int initialized = 0;
-
-/* type used to wrap pointers as list nodes */
-struct ptr_list_wrap {
-  void *ptr;
-  struct Curl_llist_element node;
-};
-
-struct cipher_s {
-  const char *name;
-  int num;
-};
-
-#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do {  \
-  CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++);                 \
-  ptr->type = (_type);                                      \
-  ptr->pValue = (_val);                                     \
-  ptr->ulValueLen = (_len);                                 \
-} while(0)
-
-#define CERT_NewTempCertificate __CERT_NewTempCertificate
-
-#define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0])
-static const struct cipher_s cipherlist[] = {
-  /* SSL2 cipher suites */
-  {"rc4",                        SSL_EN_RC4_128_WITH_MD5},
-  {"rc4-md5",                    SSL_EN_RC4_128_WITH_MD5},
-  {"rc4export",                  SSL_EN_RC4_128_EXPORT40_WITH_MD5},
-  {"rc2",                        SSL_EN_RC2_128_CBC_WITH_MD5},
-  {"rc2export",                  SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5},
-  {"des",                        SSL_EN_DES_64_CBC_WITH_MD5},
-  {"desede3",                    SSL_EN_DES_192_EDE3_CBC_WITH_MD5},
-  /* SSL3/TLS cipher suites */
-  {"rsa_rc4_128_md5",            SSL_RSA_WITH_RC4_128_MD5},
-  {"rsa_rc4_128_sha",            SSL_RSA_WITH_RC4_128_SHA},
-  {"rsa_3des_sha",               SSL_RSA_WITH_3DES_EDE_CBC_SHA},
-  {"rsa_des_sha",                SSL_RSA_WITH_DES_CBC_SHA},
-  {"rsa_rc4_40_md5",             SSL_RSA_EXPORT_WITH_RC4_40_MD5},
-  {"rsa_rc2_40_md5",             SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5},
-  {"rsa_null_md5",               SSL_RSA_WITH_NULL_MD5},
-  {"rsa_null_sha",               SSL_RSA_WITH_NULL_SHA},
-  {"fips_3des_sha",              SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA},
-  {"fips_des_sha",               SSL_RSA_FIPS_WITH_DES_CBC_SHA},
-  {"fortezza",                   SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
-  {"fortezza_rc4_128_sha",       SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
-  {"fortezza_null",              SSL_FORTEZZA_DMS_WITH_NULL_SHA},
-  {"dhe_rsa_3des_sha",           SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA},
-  {"dhe_dss_3des_sha",           SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA},
-  {"dhe_rsa_des_sha",            SSL_DHE_RSA_WITH_DES_CBC_SHA},
-  {"dhe_dss_des_sha",            SSL_DHE_DSS_WITH_DES_CBC_SHA},
-  /* TLS 1.0: Exportable 56-bit Cipher Suites. */
-  {"rsa_des_56_sha",             TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
-  {"rsa_rc4_56_sha",             TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
-  /* Ephemeral DH with RC4 bulk encryption */
-  {"dhe_dss_rc4_128_sha",    TLS_DHE_DSS_WITH_RC4_128_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. */
-  {"ecdh_ecdsa_null_sha",        TLS_ECDH_ECDSA_WITH_NULL_SHA},
-  {"ecdh_ecdsa_rc4_128_sha",     TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
-  {"ecdh_ecdsa_3des_sha",        TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA},
-  {"ecdh_ecdsa_aes_128_sha",     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA},
-  {"ecdh_ecdsa_aes_256_sha",     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA},
-  {"ecdhe_ecdsa_null_sha",       TLS_ECDHE_ECDSA_WITH_NULL_SHA},
-  {"ecdhe_ecdsa_rc4_128_sha",    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
-  {"ecdhe_ecdsa_3des_sha",       TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA},
-  {"ecdhe_ecdsa_aes_128_sha",    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
-  {"ecdhe_ecdsa_aes_256_sha",    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
-  {"ecdh_rsa_null_sha",          TLS_ECDH_RSA_WITH_NULL_SHA},
-  {"ecdh_rsa_128_sha",           TLS_ECDH_RSA_WITH_RC4_128_SHA},
-  {"ecdh_rsa_3des_sha",          TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
-  {"ecdh_rsa_aes_128_sha",       TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
-  {"ecdh_rsa_aes_256_sha",       TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
-  {"ecdhe_rsa_null",             TLS_ECDHE_RSA_WITH_NULL_SHA},
-  {"ecdhe_rsa_rc4_128_sha",      TLS_ECDHE_RSA_WITH_RC4_128_SHA},
-  {"ecdhe_rsa_3des_sha",         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
-  {"ecdhe_rsa_aes_128_sha",      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
-  {"ecdhe_rsa_aes_256_sha",      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
-  {"ecdh_anon_null_sha",         TLS_ECDH_anon_WITH_NULL_SHA},
-  {"ecdh_anon_rc4_128sha",       TLS_ECDH_anon_WITH_RC4_128_SHA},
-  {"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
-#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
-#ifdef TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
-  /* cipher suites using SHA384 */
-  {"rsa_aes_256_gcm_sha_384",         TLS_RSA_WITH_AES_256_GCM_SHA384},
-  {"dhe_rsa_aes_256_gcm_sha_384",     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
-  {"dhe_dss_aes_256_gcm_sha_384",     TLS_DHE_DSS_WITH_AES_256_GCM_SHA384},
-  {"ecdhe_ecdsa_aes_256_sha_384",     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
-  {"ecdhe_rsa_aes_256_sha_384",       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
-  {"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
-  {"ecdhe_rsa_aes_256_gcm_sha_384",   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
-#endif
-#ifdef TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
-  /* chacha20-poly1305 cipher suites */
- {"ecdhe_rsa_chacha20_poly1305_sha_256",
-     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
- {"ecdhe_ecdsa_chacha20_poly1305_sha_256",
-     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
- {"dhe_rsa_chacha20_poly1305_sha_256",
-     TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
-#endif
-#ifdef TLS_AES_256_GCM_SHA384
- {"aes_128_gcm_sha_256",              TLS_AES_128_GCM_SHA256},
- {"aes_256_gcm_sha_384",              TLS_AES_256_GCM_SHA384},
- {"chacha20_poly1305_sha_256",        TLS_CHACHA20_POLY1305_SHA256},
-#endif
-#ifdef TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
-  /* AES CBC cipher suites in RFC 5246. Introduced in NSS release 3.20 */
-  {"dhe_dss_aes_128_sha_256",         TLS_DHE_DSS_WITH_AES_128_CBC_SHA256},
-  {"dhe_dss_aes_256_sha_256",         TLS_DHE_DSS_WITH_AES_256_CBC_SHA256},
-#endif
-#ifdef TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
-  /* Camellia cipher suites in RFC 4132/5932.
-     Introduced in NSS release 3.12 */
-  {"dhe_rsa_camellia_128_sha",        TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA},
-  {"dhe_dss_camellia_128_sha",        TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA},
-  {"dhe_rsa_camellia_256_sha",        TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA},
-  {"dhe_dss_camellia_256_sha",        TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA},
-  {"rsa_camellia_128_sha",            TLS_RSA_WITH_CAMELLIA_128_CBC_SHA},
-  {"rsa_camellia_256_sha",            TLS_RSA_WITH_CAMELLIA_256_CBC_SHA},
-#endif
-#ifdef TLS_RSA_WITH_SEED_CBC_SHA
-  /* SEED cipher suite in RFC 4162. Introduced in NSS release 3.12.3 */
-  {"rsa_seed_sha",                    TLS_RSA_WITH_SEED_CBC_SHA},
-#endif
-};
-
-#if defined(WIN32)
-static const char *pem_library = "nsspem.dll";
-static const char *trust_library = "nssckbi.dll";
-#elif defined(__APPLE__)
-static const char *pem_library = "libnsspem.dylib";
-static const char *trust_library = "libnssckbi.dylib";
-#else
-static const char *pem_library = "libnsspem.so";
-static const char *trust_library = "libnssckbi.so";
-#endif
-
-static SECMODModule *pem_module = NULL;
-static SECMODModule *trust_module = NULL;
-
-/* NSPR I/O layer we use to detect blocking direction during SSL handshake */
-static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
-static PRIOMethods nspr_io_methods;
-
-static const char *nss_error_to_name(PRErrorCode code)
-{
-  const char *name = PR_ErrorToName(code);
-  if(name)
-    return name;
-
-  return "unknown error";
-}
-
-static void nss_print_error_message(struct Curl_easy *data, PRUint32 err)
-{
-  failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
-}
-
-static char *nss_sslver_to_name(PRUint16 nssver)
-{
-  switch(nssver) {
-  case SSL_LIBRARY_VERSION_2:
-    return strdup("SSLv2");
-  case SSL_LIBRARY_VERSION_3_0:
-    return strdup("SSLv3");
-  case SSL_LIBRARY_VERSION_TLS_1_0:
-    return strdup("TLSv1.0");
-#ifdef SSL_LIBRARY_VERSION_TLS_1_1
-  case SSL_LIBRARY_VERSION_TLS_1_1:
-    return strdup("TLSv1.1");
-#endif
-#ifdef SSL_LIBRARY_VERSION_TLS_1_2
-  case SSL_LIBRARY_VERSION_TLS_1_2:
-    return strdup("TLSv1.2");
-#endif
-#ifdef SSL_LIBRARY_VERSION_TLS_1_3
-  case SSL_LIBRARY_VERSION_TLS_1_3:
-    return strdup("TLSv1.3");
-#endif
-  default:
-    return curl_maprintf("0x%04x", nssver);
-  }
-}
-
-/* the longest cipher name this supports */
-#define MAX_CIPHER_LENGTH 128
-
-static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc *model,
-                             const char *cipher_list)
-{
-  unsigned int i;
-  const char *cipher;
-
-  /* use accessors to avoid dynamic linking issues after an update of NSS */
-  const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers();
-  const PRUint16 *implemented_ciphers = SSL_GetImplementedCiphers();
-  if(!implemented_ciphers)
-    return SECFailure;
-
-  /* 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 < num_implemented_ciphers; i++) {
-    SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE);
-  }
-
-  cipher = cipher_list;
-
-  while(cipher && cipher[0]) {
-    const char *end;
-    char name[MAX_CIPHER_LENGTH + 1];
-    size_t len;
-    bool found = FALSE;
-    while((*cipher) && (ISBLANK(*cipher)))
-      ++cipher;
-
-    end = strpbrk(cipher, ":, ");
-    if(end)
-      len = end - cipher;
-    else
-      len = strlen(cipher);
-
-    if(len > MAX_CIPHER_LENGTH) {
-      failf(data, "Bad cipher list");
-      return SECFailure;
-    }
-    else if(len) {
-      memcpy(name, cipher, len);
-      name[len] = 0;
-
-      for(i = 0; i<NUM_OF_CIPHERS; i++) {
-        if(strcasecompare(name, cipherlist[i].name)) {
-          /* Enable the selected cipher */
-          if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) !=
-             SECSuccess) {
-            failf(data, "cipher-suite not supported by NSS: %s", name);
-            return SECFailure;
-          }
-          found = TRUE;
-          break;
-        }
-      }
-    }
-
-    if(!found && len) {
-      failf(data, "Unknown cipher: %s", name);
-      return SECFailure;
-    }
-    if(end)
-      cipher = ++end;
-    else
-      break;
-  }
-
-  return SECSuccess;
-}
-
-/*
- * Return true if at least one cipher-suite is enabled. Used to determine
- * if we need to call NSS_SetDomesticPolicy() to enable the default ciphers.
- */
-static bool any_cipher_enabled(void)
-{
-  unsigned int i;
-
-  for(i = 0; i<NUM_OF_CIPHERS; i++) {
-    PRInt32 policy = 0;
-    SSL_CipherPolicyGet(cipherlist[i].num, &policy);
-    if(policy)
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
-/*
- * Determine whether the nickname passed in is a filename that needs to
- * be loaded as a PEM or a regular NSS nickname.
- *
- * returns 1 for a file
- * returns 0 for not a file (NSS nickname)
- */
-static int is_file(const char *filename)
-{
-  struct_stat st;
-
-  if(!filename)
-    return 0;
-
-  if(stat(filename, &st) == 0)
-    if(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISCHR(st.st_mode))
-      return 1;
-
-  return 0;
-}
-
-/* Check if the given string is filename or nickname of a certificate.  If the
- * given string is recognized as filename, return NULL.  If the given string is
- * recognized as nickname, return a duplicated string.  The returned string
- * should be later deallocated using free().  If the OOM failure occurs, we
- * return NULL, too.
- */
-static char *dup_nickname(struct Curl_easy *data, const char *str)
-{
-  const char *n;
-
-  if(!is_file(str))
-    /* no such file exists, use the string as nickname */
-    return strdup(str);
-
-  /* search the first slash; we require at least one slash in a file name */
-  n = strchr(str, '/');
-  if(!n) {
-    infof(data, "WARNING: certificate file name \"%s\" handled as nickname; "
-          "please use \"./%s\" to force file name", str, str);
-    return strdup(str);
-  }
-
-  /* we'll use the PEM reader to read the certificate from file */
-  return NULL;
-}
-
-/* Lock/unlock wrapper for PK11_FindSlotByName() to work around race condition
- * in nssSlot_IsTokenPresent() causing spurious SEC_ERROR_NO_TOKEN.  For more
- * details, go to <https://bugzilla.mozilla.org/1297397>.
- */
-static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
-{
-  PK11SlotInfo *slot;
-  PR_Lock(nss_findslot_lock);
-  slot = PK11_FindSlotByName(slot_name);
-  PR_Unlock(nss_findslot_lock);
-  return slot;
-}
-
-/* wrap 'ptr' as list node and tail-insert into 'list' */
-static CURLcode insert_wrapped_ptr(struct Curl_llist *list, void *ptr)
-{
-  struct ptr_list_wrap *wrap = malloc(sizeof(*wrap));
-  if(!wrap)
-    return CURLE_OUT_OF_MEMORY;
-
-  wrap->ptr = ptr;
-  Curl_llist_insert_next(list, list->tail, wrap, &wrap->node);
-  return CURLE_OK;
-}
-
-/* Call PK11_CreateGenericObject() with the given obj_class and filename.  If
- * the call succeeds, append the object handle to the list of objects so that
- * the object can be destroyed in nss_close(). */
-static CURLcode nss_create_object(struct ssl_connect_data *connssl,
-                                  CK_OBJECT_CLASS obj_class,
-                                  const char *filename, bool cacert)
-{
-  PK11SlotInfo *slot;
-  PK11GenericObject *obj;
-  CK_BBOOL cktrue = CK_TRUE;
-  CK_BBOOL ckfalse = CK_FALSE;
-  CK_ATTRIBUTE attrs[/* max count of attributes */ 4];
-  int attr_cnt = 0;
-  CURLcode result = (cacert)
-    ? CURLE_SSL_CACERT_BADFILE
-    : CURLE_SSL_CERTPROBLEM;
-
-  const int slot_id = (cacert) ? 0 : 1;
-  char *slot_name = aprintf("PEM Token #%d", slot_id);
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-
-  DEBUGASSERT(backend);
-
-  if(!slot_name)
-    return CURLE_OUT_OF_MEMORY;
-
-  slot = nss_find_slot_by_name(slot_name);
-  free(slot_name);
-  if(!slot)
-    return result;
-
-  PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
-  PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
-  PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename,
-                (CK_ULONG)strlen(filename) + 1);
-
-  if(CKO_CERTIFICATE == obj_class) {
-    CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse);
-    PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval));
-  }
-
-  /* PK11_CreateManagedGenericObject() was introduced in NSS 3.34 because
-   * PK11_DestroyGenericObject() does not release resources allocated by
-   * PK11_CreateGenericObject() early enough.  */
-  obj =
-#ifdef HAVE_PK11_CREATEMANAGEDGENERICOBJECT
-    PK11_CreateManagedGenericObject
-#else
-    PK11_CreateGenericObject
-#endif
-    (slot, attrs, attr_cnt, PR_FALSE);
-
-  PK11_FreeSlot(slot);
-  if(!obj)
-    return result;
-
-  if(insert_wrapped_ptr(&backend->obj_list, obj) != CURLE_OK) {
-    PK11_DestroyGenericObject(obj);
-    return CURLE_OUT_OF_MEMORY;
-  }
-
-  if(!cacert && CKO_CERTIFICATE == obj_class)
-    /* store reference to a client certificate */
-    backend->obj_clicert = obj;
-
-  return CURLE_OK;
-}
-
-/* Destroy the NSS object whose handle is given by ptr.  This function is
- * a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy
- * NSS objects in nss_close() */
-static void nss_destroy_object(void *user, void *ptr)
-{
-  struct ptr_list_wrap *wrap = (struct ptr_list_wrap *) ptr;
-  PK11GenericObject *obj = (PK11GenericObject *) wrap->ptr;
-  (void) user;
-  PK11_DestroyGenericObject(obj);
-  free(wrap);
-}
-
-/* same as nss_destroy_object() but for CRL items */
-static void nss_destroy_crl_item(void *user, void *ptr)
-{
-  struct ptr_list_wrap *wrap = (struct ptr_list_wrap *) ptr;
-  SECItem *crl_der = (SECItem *) wrap->ptr;
-  (void) user;
-  SECITEM_FreeItem(crl_der, PR_TRUE);
-  free(wrap);
-}
-
-static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
-                              const char *filename, PRBool cacert)
-{
-  CURLcode result = (cacert)
-    ? CURLE_SSL_CACERT_BADFILE
-    : CURLE_SSL_CERTPROBLEM;
-
-  /* libnsspem.so leaks memory if the requested file does not exist.  For more
-   * details, go to <https://bugzilla.redhat.com/734760>. */
-  if(is_file(filename))
-    result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
-
-  if(!result && !cacert) {
-    /* we have successfully loaded a client certificate */
-    char *nickname = NULL;
-    char *n = strrchr(filename, '/');
-    if(n)
-      n++;
-
-    /* The following undocumented magic helps to avoid a SIGSEGV on call
-     * of PK11_ReadRawAttribute() from SelectClientCert() when using an
-     * immature version of libnsspem.so.  For more details, go to
-     * <https://bugzilla.redhat.com/733685>. */
-    nickname = aprintf("PEM Token #1:%s", n);
-    if(nickname) {
-      CERTCertificate *cert = PK11_FindCertFromNickname(nickname, NULL);
-      if(cert)
-        CERT_DestroyCertificate(cert);
-
-      free(nickname);
-    }
-  }
-
-  return result;
-}
-
-/* add given CRL to cache if it is not already there */
-static CURLcode nss_cache_crl(SECItem *crl_der)
-{
-  CERTCertDBHandle *db = CERT_GetDefaultCertDB();
-  CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
-  if(crl) {
-    /* CRL already cached */
-    SEC_DestroyCrl(crl);
-    SECITEM_FreeItem(crl_der, PR_TRUE);
-    return CURLE_OK;
-  }
-
-  /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
-  PR_Lock(nss_crllock);
-
-  if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
-    /* unable to cache CRL */
-    SECITEM_FreeItem(crl_der, PR_TRUE);
-    PR_Unlock(nss_crllock);
-    return CURLE_SSL_CRL_BADFILE;
-  }
-
-  /* store the CRL item so that we can free it in nss_cleanup() */
-  if(insert_wrapped_ptr(&nss_crl_list, crl_der) != CURLE_OK) {
-    if(SECSuccess == CERT_UncacheCRL(db, crl_der))
-      SECITEM_FreeItem(crl_der, PR_TRUE);
-    PR_Unlock(nss_crllock);
-    return CURLE_OUT_OF_MEMORY;
-  }
-
-  /* we need to clear session cache, so that the CRL could take effect */
-  SSL_ClearSessionCache();
-  PR_Unlock(nss_crllock);
-  return CURLE_OK;
-}
-
-static CURLcode nss_load_crl(const char *crlfilename)
-{
-  PRFileDesc *infile;
-  PRFileInfo  info;
-  SECItem filedata = { 0, NULL, 0 };
-  SECItem *crl_der = NULL;
-  char *body;
-
-  infile = PR_Open(crlfilename, PR_RDONLY, 0);
-  if(!infile)
-    return CURLE_SSL_CRL_BADFILE;
-
-  if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info))
-    goto fail;
-
-  if(!SECITEM_AllocItem(NULL, &filedata, info.size + /* zero ended */ 1))
-    goto fail;
-
-  if(info.size != PR_Read(infile, filedata.data, info.size))
-    goto fail;
-
-  crl_der = SECITEM_AllocItem(NULL, NULL, 0U);
-  if(!crl_der)
-    goto fail;
-
-  /* place a trailing zero right after the visible data */
-  body = (char *)filedata.data;
-  body[--filedata.len] = '\0';
-
-  body = strstr(body, "-----BEGIN");
-  if(body) {
-    /* assume ASCII */
-    char *trailer;
-    char *begin = PORT_Strchr(body, '\n');
-    if(!begin)
-      begin = PORT_Strchr(body, '\r');
-    if(!begin)
-      goto fail;
-
-    trailer = strstr(++begin, "-----END");
-    if(!trailer)
-      goto fail;
-
-    /* retrieve DER from ASCII */
-    *trailer = '\0';
-    if(ATOB_ConvertAsciiToItem(crl_der, begin))
-      goto fail;
-
-    SECITEM_FreeItem(&filedata, PR_FALSE);
-  }
-  else
-    /* assume DER */
-    *crl_der = filedata;
-
-  PR_Close(infile);
-  return nss_cache_crl(crl_der);
-
-fail:
-  PR_Close(infile);
-  SECITEM_FreeItem(crl_der, PR_TRUE);
-  SECITEM_FreeItem(&filedata, PR_FALSE);
-  return CURLE_SSL_CRL_BADFILE;
-}
-
-static CURLcode nss_load_key(struct Curl_cfilter *cf,
-                             struct Curl_easy *data,
-                             char *key_file)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
-  PK11SlotInfo *slot, *tmp;
-  SECStatus status;
-  CURLcode result;
-
-  (void)data;
-  result = nss_create_object(connssl, CKO_PRIVATE_KEY, key_file, FALSE);
-  if(result) {
-    PR_SetError(SEC_ERROR_BAD_KEY, 0);
-    return result;
-  }
-
-  slot = nss_find_slot_by_name("PEM Token #1");
-  if(!slot)
-    return CURLE_SSL_CERTPROBLEM;
-
-  /* This will force the token to be seen as re-inserted */
-  tmp = SECMOD_WaitForAnyTokenEvent(pem_module, 0, 0);
-  if(tmp)
-    PK11_FreeSlot(tmp);
-  if(!PK11_IsPresent(slot)) {
-    PK11_FreeSlot(slot);
-    return CURLE_SSL_CERTPROBLEM;
-  }
-
-  status = PK11_Authenticate(slot, PR_TRUE, ssl_config->key_passwd);
-  PK11_FreeSlot(slot);
-
-  return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
-}
-
-static int display_error(struct Curl_easy *data, PRInt32 err,
-                         const char *filename)
-{
-  switch(err) {
-  case SEC_ERROR_BAD_PASSWORD:
-    failf(data, "Unable to load client key: Incorrect password");
-    return 1;
-  case SEC_ERROR_UNKNOWN_CERT:
-    failf(data, "Unable to load certificate %s", filename);
-    return 1;
-  default:
-    break;
-  }
-  return 0; /* The caller will print a generic error */
-}
-
-static CURLcode cert_stuff(struct Curl_cfilter *cf,
-                           struct Curl_easy *data,
-                           char *cert_file, char *key_file)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  CURLcode result;
-
-  if(cert_file) {
-    result = nss_load_cert(connssl, cert_file, PR_FALSE);
-    if(result) {
-      const PRErrorCode err = PR_GetError();
-      if(!display_error(data, err, cert_file)) {
-        const char *err_name = nss_error_to_name(err);
-        failf(data, "unable to load client cert: %d (%s)", err, err_name);
-      }
-
-      return result;
-    }
-  }
-
-  if(key_file || (is_file(cert_file))) {
-    if(key_file)
-      result = nss_load_key(cf, data, key_file);
-    else
-      /* In case the cert file also has the key */
-      result = nss_load_key(cf, data, cert_file);
-    if(result) {
-      const PRErrorCode err = PR_GetError();
-      if(!display_error(data, err, key_file)) {
-        const char *err_name = nss_error_to_name(err);
-        failf(data, "unable to load client key: %d (%s)", err, err_name);
-      }
-
-      return result;
-    }
-  }
-
-  return CURLE_OK;
-}
-
-static char *nss_get_password(PK11SlotInfo *slot, PRBool retry, void *arg)
-{
-  (void)slot; /* unused */
-
-  if(retry || !arg)
-    return NULL;
-  else
-    return (char *)PORT_Strdup((char *)arg);
-}
-
-/* bypass the default SSL_AuthCertificate() hook in case we do not want to
- * verify peer */
-static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
-                                    PRBool isServer)
-{
-  struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  struct Curl_easy *data = backend->data;
-
-  DEBUGASSERT(data);
-#ifdef SSL_ENABLE_OCSP_STAPLING
-  if(conn_config->verifystatus) {
-    SECStatus cacheResult;
-
-    const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
-    if(!csa) {
-      failf(data, "Invalid OCSP response");
-      return SECFailure;
-    }
-
-    if(csa->len == 0) {
-      failf(data, "No OCSP response received");
-      return SECFailure;
-    }
-
-    cacheResult = CERT_CacheOCSPResponseFromSideChannel(
-      CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd),
-      PR_Now(), &csa->items[0], arg
-    );
-
-    if(cacheResult != SECSuccess) {
-      failf(data, "Invalid OCSP response");
-      return cacheResult;
-    }
-  }
-#endif
-
-  if(!conn_config->verifypeer) {
-    infof(data, "skipping SSL peer certificate verification");
-    return SECSuccess;
-  }
-
-  return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer);
-}
-
-/**
- * Inform the application that the handshake is complete.
- */
-static void HandshakeCallback(PRFileDesc *sock, void *arg)
-{
-  struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  struct Curl_easy *data = backend->data;
-  unsigned int buflenmax = 50;
-  unsigned char buf[50];
-  unsigned int buflen;
-  SSLNextProtoState state;
-
-  DEBUGASSERT(data);
-  if(!connssl->alpn) {
-    return;
-  }
-
-  if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) {
-
-    switch(state) {
-#if NSSVERNUM >= 0x031a00 /* 3.26.0 */
-    /* used by NSS internally to implement 0-RTT */
-    case SSL_NEXT_PROTO_EARLY_VALUE:
-      /* fall through! */
-#endif
-    case SSL_NEXT_PROTO_NO_SUPPORT:
-    case SSL_NEXT_PROTO_NO_OVERLAP:
-      Curl_alpn_set_negotiated(cf, data, NULL, 0);
-      return;
-#ifdef SSL_ENABLE_ALPN
-    case SSL_NEXT_PROTO_SELECTED:
-      Curl_alpn_set_negotiated(cf, data, buf, buflen);
-      break;
-#endif
-    default:
-      /* ignore SSL_NEXT_PROTO_NEGOTIATED */
-      break;
-    }
-
-  }
-}
-
-#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
-static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data,
-                                       PRBool *canFalseStart)
-{
-  struct Curl_easy *data = (struct Curl_easy *)client_data;
-
-  SSLChannelInfo channelInfo;
-  SSLCipherSuiteInfo cipherInfo;
-
-  SECStatus rv;
-  PRBool negotiatedExtension;
-
-  *canFalseStart = PR_FALSE;
-
-  if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess)
-    return SECFailure;
-
-  if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
-                            sizeof(cipherInfo)) != SECSuccess)
-    return SECFailure;
-
-  /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for
-   * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310
-   */
-  if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2)
-    goto end;
-
-  /* Only allow ECDHE key exchange algorithm.
-   * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */
-  if(cipherInfo.keaType != ssl_kea_ecdh)
-    goto end;
-
-  /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC
-   * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt
-   * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */
-  if(cipherInfo.symCipher != ssl_calg_aes_gcm)
-    goto end;
-
-  /* Enforce ALPN to do False Start, as an indicator of server
-     compatibility. */
-  rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
-                                        &negotiatedExtension);
-  if(rv != SECSuccess || !negotiatedExtension) {
-    rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn,
-                                          &negotiatedExtension);
-  }
-
-  if(rv != SECSuccess || !negotiatedExtension)
-    goto end;
-
-  *canFalseStart = PR_TRUE;
-
-  infof(data, "Trying TLS False Start");
-
-end:
-  return SECSuccess;
-}
-#endif
-
-static void display_cert_info(struct Curl_easy *data,
-                              CERTCertificate *cert)
-{
-  char *subject, *issuer, *common_name;
-  PRExplodedTime printableTime;
-  char timeString[256];
-  PRTime notBefore, notAfter;
-
-  subject = CERT_NameToAscii(&cert->subject);
-  issuer = CERT_NameToAscii(&cert->issuer);
-  common_name = CERT_GetCommonName(&cert->subject);
-  infof(data, "subject: %s", subject);
-
-  CERT_GetCertTimes(cert, &notBefore, &notAfter);
-  PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
-  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
-  infof(data, " start date: %s", timeString);
-  PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
-  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
-  infof(data, " expire date: %s", timeString);
-  infof(data, " common name: %s", common_name);
-  infof(data, " issuer: %s", issuer);
-
-  PR_Free(subject);
-  PR_Free(issuer);
-  PR_Free(common_name);
-}
-
-/* A number of certs that will never occur in a real server handshake */
-#define TOO_MANY_CERTS 300
-
-static CURLcode display_conn_info(struct Curl_easy *data, PRFileDesc *sock)
-{
-  CURLcode result = CURLE_OK;
-  SSLChannelInfo channel;
-  SSLCipherSuiteInfo suite;
-  CERTCertificate *cert;
-  CERTCertificate *cert2;
-  CERTCertificate *cert3;
-  PRTime now;
-
-  if(SSL_GetChannelInfo(sock, &channel, sizeof(channel)) ==
-     SECSuccess && channel.length == sizeof(channel) &&
-     channel.cipherSuite) {
-    if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
-                              &suite, sizeof(suite)) == SECSuccess) {
-      infof(data, "SSL connection using %s", suite.cipherSuiteName);
-    }
-  }
-
-  cert = SSL_PeerCertificate(sock);
-  if(cert) {
-    infof(data, "Server certificate:");
-
-    if(!data->set.ssl.certinfo) {
-      display_cert_info(data, cert);
-      CERT_DestroyCertificate(cert);
-    }
-    else {
-      /* Count certificates in chain. */
-      int i = 1;
-      now = PR_Now();
-      if(!cert->isRoot) {
-        cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
-        while(cert2) {
-          i++;
-          if(i >= TOO_MANY_CERTS) {
-            CERT_DestroyCertificate(cert2);
-            failf(data, "certificate loop");
-            return CURLE_SSL_CERTPROBLEM;
-          }
-          if(cert2->isRoot) {
-            CERT_DestroyCertificate(cert2);
-            break;
-          }
-          cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
-          CERT_DestroyCertificate(cert2);
-          cert2 = cert3;
-        }
-      }
-
-      result = Curl_ssl_init_certinfo(data, i);
-      if(!result) {
-        for(i = 0; cert; cert = cert2) {
-          result = Curl_extract_certinfo(data, i++, (char *)cert->derCert.data,
-                                         (char *)cert->derCert.data +
-                                                 cert->derCert.len);
-          if(result)
-            break;
-
-          if(cert->isRoot) {
-            CERT_DestroyCertificate(cert);
-            break;
-          }
-
-          cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
-          CERT_DestroyCertificate(cert);
-        }
-      }
-    }
-  }
-
-  return result;
-}
-
-static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
-{
-  struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  struct Curl_easy *data = backend->data;
-  struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
-  struct ssl_config_data *ssl_config;
-  PRErrorCode err = PR_GetError();
-  CERTCertificate *cert;
-
-  DEBUGASSERT(data);
-  ssl_config = Curl_ssl_cf_get_config(cf, data);
-  /* remember the cert verification result */
-  ssl_config->certverifyresult = err;
-
-  if(err == SSL_ERROR_BAD_CERT_DOMAIN && !conn_config->verifyhost)
-    /* we are asked not to verify the host name */
-    return SECSuccess;
-
-  /* print only info about the cert, the error is printed off the callback */
-  cert = SSL_PeerCertificate(sock);
-  if(cert) {
-    infof(data, "Server certificate:");
-    display_cert_info(data, cert);
-    CERT_DestroyCertificate(cert);
-  }
-
-  return SECFailure;
-}
-
-/**
- *
- * Check that the Peer certificate's issuer certificate matches the one found
- * by issuer_nickname.  This is not exactly the way OpenSSL and GNU TLS do the
- * issuer check, so we provide comments that mimic the OpenSSL
- * X509_check_issued function (in x509v3/v3_purp.c)
- */
-static SECStatus check_issuer_cert(PRFileDesc *sock,
-                                   char *issuer_nickname)
-{
-  CERTCertificate *cert, *cert_issuer, *issuer;
-  SECStatus res = SECSuccess;
-  void *proto_win = NULL;
-
-  cert = SSL_PeerCertificate(sock);
-  cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner);
-
-  proto_win = SSL_RevealPinArg(sock);
-  issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
-
-  if((!cert_issuer) || (!issuer))
-    res = SECFailure;
-  else if(SECITEM_CompareItem(&cert_issuer->derCert,
-                              &issuer->derCert) != SECEqual)
-    res = SECFailure;
-
-  CERT_DestroyCertificate(cert);
-  CERT_DestroyCertificate(issuer);
-  CERT_DestroyCertificate(cert_issuer);
-  return res;
-}
-
-static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
-                                const char *pinnedpubkey)
-{
-  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  struct Curl_easy *data = NULL;
-  CERTCertificate *cert;
-
-  DEBUGASSERT(backend);
-  data = backend->data;
-
-  if(!pinnedpubkey)
-    /* no pinned public key specified */
-    return CURLE_OK;
-
-  /* get peer certificate */
-  cert = SSL_PeerCertificate(backend->handle);
-  if(cert) {
-    /* extract public key from peer certificate */
-    SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
-    if(pubkey) {
-      /* encode the public key as DER */
-      SECItem *cert_der = PK11_DEREncodePublicKey(pubkey);
-      if(cert_der) {
-        /* compare the public key with the pinned public key */
-        result = Curl_pin_peer_pubkey(data, pinnedpubkey, cert_der->data,
-                                      cert_der->len);
-        SECITEM_FreeItem(cert_der, PR_TRUE);
-      }
-      SECKEY_DestroyPublicKey(pubkey);
-    }
-    CERT_DestroyCertificate(cert);
-  }
-
-  /* report the resulting status */
-  switch(result) {
-  case CURLE_OK:
-    infof(data, "pinned public key verified successfully");
-    break;
-  case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
-    failf(data, "failed to verify pinned public key");
-    break;
-  default:
-    /* OOM, etc. */
-    break;
-  }
-
-  return result;
-}
-
-/**
- *
- * Callback to pick the SSL client certificate.
- */
-static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
-                                  struct CERTDistNamesStr *caNames,
-                                  struct CERTCertificateStr **pRetCert,
-                                  struct SECKEYPrivateKeyStr **pRetKey)
-{
-  struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  struct Curl_easy *data = NULL;
-  const char *nickname = NULL;
-  static const char pem_slotname[] = "PEM Token #1";
-
-  DEBUGASSERT(backend);
-
-  data = backend->data;
-  nickname = backend->client_nickname;
-
-  if(backend->obj_clicert) {
-    /* use the cert/key provided by PEM reader */
-    SECItem cert_der = { 0, NULL, 0 };
-    void *proto_win = SSL_RevealPinArg(sock);
-    struct CERTCertificateStr *cert;
-    struct SECKEYPrivateKeyStr *key;
-
-    PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
-    if(!slot) {
-      failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
-      return SECFailure;
-    }
-
-    if(PK11_ReadRawAttribute(PK11_TypeGeneric, backend->obj_clicert, CKA_VALUE,
-                             &cert_der) != SECSuccess) {
-      failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
-      PK11_FreeSlot(slot);
-      return SECFailure;
-    }
-
-    cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
-    SECITEM_FreeItem(&cert_der, PR_FALSE);
-    if(!cert) {
-      failf(data, "NSS: client certificate from file not found");
-      PK11_FreeSlot(slot);
-      return SECFailure;
-    }
-
-    key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
-    PK11_FreeSlot(slot);
-    if(!key) {
-      failf(data, "NSS: private key from file not found");
-      CERT_DestroyCertificate(cert);
-      return SECFailure;
-    }
-
-    infof(data, "NSS: client certificate from file");
-    display_cert_info(data, cert);
-
-    *pRetCert = cert;
-    *pRetKey = key;
-    return SECSuccess;
-  }
-
-  /* use the default NSS hook */
-  if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
-                                          pRetCert, pRetKey)
-     || !*pRetCert) {
-
-    if(!nickname)
-      failf(data, "NSS: client certificate not found (nickname not "
-            "specified)");
-    else
-      failf(data, "NSS: client certificate not found: %s", nickname);
-
-    return SECFailure;
-  }
-
-  /* get certificate nickname if any */
-  nickname = (*pRetCert)->nickname;
-  if(!nickname)
-    nickname = "[unknown]";
-
-  if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) {
-    failf(data, "NSS: refusing previously loaded certificate from file: %s",
-          nickname);
-    return SECFailure;
-  }
-
-  if(!*pRetKey) {
-    failf(data, "NSS: private key not found for certificate: %s", nickname);
-    return SECFailure;
-  }
-
-  infof(data, "NSS: using client certificate: %s", nickname);
-  display_cert_info(data, *pRetCert);
-  return SECSuccess;
-}
-
-/* update blocking direction in case of PR_WOULD_BLOCK_ERROR */
-static void nss_update_connecting_state(ssl_connect_state state, void *secret)
-{
-  struct ssl_connect_data *connssl = (struct ssl_connect_data *)secret;
-  if(PR_GetError() != PR_WOULD_BLOCK_ERROR)
-    /* an unrelated error is passing by */
-    return;
-
-  switch(connssl->connecting_state) {
-  case ssl_connect_2:
-  case ssl_connect_2_reading:
-  case ssl_connect_2_writing:
-    break;
-  default:
-    /* we are not called from an SSL handshake */
-    return;
-  }
-
-  /* update the state accordingly */
-  connssl->connecting_state = state;
-}
-
-/* recv() wrapper we use to detect blocking direction during SSL handshake */
-static PRInt32 nspr_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
-                            PRIntn flags, PRIntervalTime timeout)
-{
-  const PRRecvFN recv_fn = fd->lower->methods->recv;
-  const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout);
-  if(rv < 0)
-    /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
-    nss_update_connecting_state(ssl_connect_2_reading, fd->secret);
-  return rv;
-}
-
-/* send() wrapper we use to detect blocking direction during SSL handshake */
-static PRInt32 nspr_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
-                            PRIntn flags, PRIntervalTime timeout)
-{
-  const PRSendFN send_fn = fd->lower->methods->send;
-  const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout);
-  if(rv < 0)
-    /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
-    nss_update_connecting_state(ssl_connect_2_writing, fd->secret);
-  return rv;
-}
-
-/* close() wrapper to avoid assertion failure due to fd->secret != NULL */
-static PRStatus nspr_io_close(PRFileDesc *fd)
-{
-  const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close;
-  fd->secret = NULL;
-  return close_fn(fd);
-}
-
-/* load a PKCS #11 module */
-static CURLcode nss_load_module(SECMODModule **pmod, const char *library,
-                                const char *name)
-{
-  char *config_string;
-  SECMODModule *module = *pmod;
-  if(module)
-    /* already loaded */
-    return CURLE_OK;
-
-  config_string = aprintf("library=%s name=%s", library, name);
-  if(!config_string)
-    return CURLE_OUT_OF_MEMORY;
-
-  module = SECMOD_LoadUserModule(config_string, NULL, PR_FALSE);
-  free(config_string);
-
-  if(module && module->loaded) {
-    /* loaded successfully */
-    *pmod = module;
-    return CURLE_OK;
-  }
-
-  if(module)
-    SECMOD_DestroyModule(module);
-  return CURLE_FAILED_INIT;
-}
-
-/* unload a PKCS #11 module */
-static void nss_unload_module(SECMODModule **pmod)
-{
-  SECMODModule *module = *pmod;
-  if(!module)
-    /* not loaded */
-    return;
-
-  if(SECMOD_UnloadUserModule(module) != SECSuccess)
-    /* unload failed */
-    return;
-
-  SECMOD_DestroyModule(module);
-  *pmod = NULL;
-}
-
-/* data might be NULL */
-static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
-{
-  NSSInitParameters initparams;
-  PRErrorCode err;
-  const char *err_name;
-
-  if(nss_context)
-    return CURLE_OK;
-
-  memset((void *) &initparams, '\0', sizeof(initparams));
-  initparams.length = sizeof(initparams);
-
-  if(cert_dir) {
-    char *certpath = aprintf("sql:%s", cert_dir);
-    if(!certpath)
-      return CURLE_OUT_OF_MEMORY;
-
-    infof(data, "Initializing NSS with certpath: %s", certpath);
-    nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
-                                  NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
-    free(certpath);
-
-    if(nss_context)
-      return CURLE_OK;
-
-    err = PR_GetError();
-    err_name = nss_error_to_name(err);
-    infof(data, "Unable to initialize NSS database: %d (%s)", err, err_name);
-  }
-
-  infof(data, "Initializing NSS with certpath: none");
-  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)
-    return CURLE_OK;
-
-  err = PR_GetError();
-  err_name = nss_error_to_name(err);
-  failf(data, "Unable to initialize NSS: %d (%s)", err, err_name);
-  return CURLE_SSL_CACERT_BADFILE;
-}
-
-/* data might be NULL */
-static CURLcode nss_setup(struct Curl_easy *data)
-{
-  char *cert_dir;
-  struct_stat st;
-  CURLcode result;
-
-  if(initialized)
-    return CURLE_OK;
-
-  /* list of all CRL items we need to destroy in nss_cleanup() */
-  Curl_llist_init(&nss_crl_list, nss_destroy_crl_item);
-
-  /* First we check if $SSL_DIR points to a valid dir */
-  cert_dir = getenv("SSL_DIR");
-  if(cert_dir) {
-    if((stat(cert_dir, &st) != 0) ||
-        (!S_ISDIR(st.st_mode))) {
-      cert_dir = NULL;
-    }
-  }
-
-  /* Now we check if the default location is a valid dir */
-  if(!cert_dir) {
-    if((stat(SSL_DIR, &st) == 0) &&
-        (S_ISDIR(st.st_mode))) {
-      cert_dir = (char *)SSL_DIR;
-    }
-  }
-
-  if(nspr_io_identity == PR_INVALID_IO_LAYER) {
-    /* allocate an identity for our own NSPR I/O layer */
-    nspr_io_identity = PR_GetUniqueIdentity("libcurl");
-    if(nspr_io_identity == PR_INVALID_IO_LAYER)
-      return CURLE_OUT_OF_MEMORY;
-
-    /* the default methods just call down to the lower I/O layer */
-    memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(),
-           sizeof(nspr_io_methods));
-
-    /* override certain methods in the table by our wrappers */
-    nspr_io_methods.recv  = nspr_io_recv;
-    nspr_io_methods.send  = nspr_io_send;
-    nspr_io_methods.close = nspr_io_close;
-  }
-
-  result = nss_init_core(data, cert_dir);
-  if(result)
-    return result;
-
-  if(!any_cipher_enabled())
-    NSS_SetDomesticPolicy();
-
-  initialized = 1;
-
-  return CURLE_OK;
-}
-
-/**
- * Global SSL init
- *
- * @retval 0 error initializing SSL
- * @retval 1 SSL initialized successfully
- */
-static int nss_init(void)
-{
-  /* curl_global_init() is not thread-safe so this test is ok */
-  if(!nss_initlock) {
-    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
-    nss_initlock = PR_NewLock();
-    nss_crllock = PR_NewLock();
-    nss_findslot_lock = PR_NewLock();
-    nss_trustload_lock = PR_NewLock();
-  }
-
-  /* We will actually initialize NSS later */
-
-  return 1;
-}
-
-/* data might be NULL */
-CURLcode Curl_nss_force_init(struct Curl_easy *data)
-{
-  CURLcode result;
-  if(!nss_initlock) {
-    if(data)
-      failf(data, "unable to initialize NSS, curl_global_init() should have "
-                  "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
-    return CURLE_FAILED_INIT;
-  }
-
-  PR_Lock(nss_initlock);
-  result = nss_setup(data);
-  PR_Unlock(nss_initlock);
-
-  return result;
-}
-
-/* Global cleanup */
-static void nss_cleanup(void)
-{
-  /* This function isn't required to be threadsafe and this is only done
-   * as a safety feature.
-   */
-  PR_Lock(nss_initlock);
-  if(initialized) {
-    /* Free references to client certificates held in the SSL session cache.
-     * Omitting this hampers destruction of the security module owning
-     * the certificates. */
-    SSL_ClearSessionCache();
-
-    nss_unload_module(&pem_module);
-    nss_unload_module(&trust_module);
-    NSS_ShutdownContext(nss_context);
-    nss_context = NULL;
-  }
-
-  /* destroy all CRL items */
-  Curl_llist_destroy(&nss_crl_list, NULL);
-
-  PR_Unlock(nss_initlock);
-
-  PR_DestroyLock(nss_initlock);
-  PR_DestroyLock(nss_crllock);
-  PR_DestroyLock(nss_findslot_lock);
-  PR_DestroyLock(nss_trustload_lock);
-  nss_initlock = NULL;
-
-  initialized = 0;
-}
-
-static void close_one(struct ssl_connect_data *connssl)
-{
-  /* before the cleanup, check whether we are using a client certificate */
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  bool client_cert = true;
-
-  DEBUGASSERT(backend);
-
-  client_cert = (backend->client_nickname != NULL)
-    || (backend->obj_clicert != NULL);
-
-  if(backend->handle) {
-    char buf[32];
-    /* Maybe the server has already sent a close notify alert.
-       Read it to avoid an RST on the TCP connection. */
-    (void)PR_Recv(backend->handle, buf, (int)sizeof(buf), 0,
-                  PR_INTERVAL_NO_WAIT);
-  }
-
-  free(backend->client_nickname);
-  backend->client_nickname = NULL;
-
-  /* destroy all NSS objects in order to avoid failure of NSS shutdown */
-  Curl_llist_destroy(&backend->obj_list, NULL);
-  backend->obj_clicert = NULL;
-
-  if(backend->handle) {
-    if(client_cert)
-      /* A server might require different authentication based on the
-       * particular path being requested by the client.  To support this
-       * scenario, we must ensure that a connection will never reuse the
-       * authentication data from a previous connection. */
-      SSL_InvalidateSession(backend->handle);
-
-    PR_Close(backend->handle);
-    backend->handle = NULL;
-  }
-}
-
-/*
- * This function is called when an SSL connection is closed.
- */
-static void nss_close(struct Curl_cfilter *cf, struct Curl_easy *data)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  (void)data;
-  DEBUGASSERT(backend);
-
-  if(backend->handle) {
-    /* NSS closes the socket we previously handed to it, so we must mark it
-       as closed to avoid double close */
-    fake_sclose(cf->conn->sock[cf->sockindex]);
-    cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD;
-  }
-
-  close_one(connssl);
-}
-
-/* return true if NSS can provide error code (and possibly msg) for the
-   error */
-static bool is_nss_error(CURLcode err)
-{
-  switch(err) {
-  case CURLE_PEER_FAILED_VERIFICATION:
-  case CURLE_SSL_CERTPROBLEM:
-  case CURLE_SSL_CONNECT_ERROR:
-  case CURLE_SSL_ISSUER_ERROR:
-    return true;
-
-  default:
-    return false;
-  }
-}
-
-/* return true if the given error code is related to a client certificate */
-static bool is_cc_error(PRInt32 err)
-{
-  switch(err) {
-  case SSL_ERROR_BAD_CERT_ALERT:
-  case SSL_ERROR_EXPIRED_CERT_ALERT:
-  case SSL_ERROR_REVOKED_CERT_ALERT:
-    return true;
-
-  default:
-    return false;
-  }
-}
-
-static CURLcode nss_load_ca_certificates(struct Curl_cfilter *cf,
-                                         struct Curl_easy *data)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
-  const char *cafile = conn_config->CAfile;
-  const char *capath = conn_config->CApath;
-  bool use_trust_module;
-  CURLcode result = CURLE_OK;
-
-  /* treat empty string as unset */
-  if(cafile && !cafile[0])
-    cafile = NULL;
-  if(capath && !capath[0])
-    capath = NULL;
-
-  infof(data, " CAfile: %s", cafile ? cafile : "none");
-  infof(data, " CApath: %s", capath ? capath : "none");
-
-  /* load libnssckbi.so if no other trust roots were specified */
-  use_trust_module = !cafile && !capath;
-
-  PR_Lock(nss_trustload_lock);
-  if(use_trust_module && !trust_module) {
-    /* libnssckbi.so needed but not yet loaded --> load it! */
-    result = nss_load_module(&trust_module, trust_library, "trust");
-    infof(data, "%s %s", (result) ? "failed to load" : "loaded",
-          trust_library);
-    if(result == CURLE_FAILED_INIT)
-      /* If libnssckbi.so is not available (or fails to load), one can still
-         use CA certificates stored in NSS database.  Ignore the failure. */
-      result = CURLE_OK;
-  }
-  else if(!use_trust_module && trust_module) {
-    /* libnssckbi.so not needed but already loaded --> unload it! */
-    infof(data, "unloading %s", trust_library);
-    nss_unload_module(&trust_module);
-  }
-  PR_Unlock(nss_trustload_lock);
-
-  if(cafile)
-    result = nss_load_cert(connssl, cafile, PR_TRUE);
-
-  if(result)
-    return result;
-
-  if(capath) {
-    struct_stat st;
-    if(stat(capath, &st) == -1)
-      return CURLE_SSL_CACERT_BADFILE;
-
-    if(S_ISDIR(st.st_mode)) {
-      PRDirEntry *entry;
-      PRDir *dir = PR_OpenDir(capath);
-      if(!dir)
-        return CURLE_SSL_CACERT_BADFILE;
-
-      while((entry =
-             PR_ReadDir(dir, (PRDirFlags)(PR_SKIP_BOTH | PR_SKIP_HIDDEN)))) {
-        char *fullpath = aprintf("%s/%s", capath, entry->name);
-        if(!fullpath) {
-          PR_CloseDir(dir);
-          return CURLE_OUT_OF_MEMORY;
-        }
-
-        if(CURLE_OK != nss_load_cert(connssl, fullpath, PR_TRUE))
-          /* This is purposefully tolerant of errors so non-PEM files can
-           * be in the same directory */
-          infof(data, "failed to load '%s' from CURLOPT_CAPATH", fullpath);
-
-        free(fullpath);
-      }
-
-      PR_CloseDir(dir);
-    }
-    else
-      infof(data, "WARNING: CURLOPT_CAPATH not a directory (%s)", capath);
-  }
-
-  return CURLE_OK;
-}
-
-static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version)
-{
-  switch(version) {
-  case CURL_SSLVERSION_SSLv2:
-    *nssver = SSL_LIBRARY_VERSION_2;
-    return CURLE_OK;
-
-  case CURL_SSLVERSION_SSLv3:
-    return CURLE_NOT_BUILT_IN;
-
-  case CURL_SSLVERSION_TLSv1_0:
-    *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
-    return CURLE_OK;
-
-  case CURL_SSLVERSION_TLSv1_1:
-#ifdef SSL_LIBRARY_VERSION_TLS_1_1
-    *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
-    return CURLE_OK;
-#else
-    return CURLE_SSL_CONNECT_ERROR;
-#endif
-
-  case CURL_SSLVERSION_TLSv1_2:
-#ifdef SSL_LIBRARY_VERSION_TLS_1_2
-    *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
-    return CURLE_OK;
-#else
-    return CURLE_SSL_CONNECT_ERROR;
-#endif
-
-  case CURL_SSLVERSION_TLSv1_3:
-#ifdef SSL_LIBRARY_VERSION_TLS_1_3
-    *nssver = SSL_LIBRARY_VERSION_TLS_1_3;
-    return CURLE_OK;
-#else
-    return CURLE_SSL_CONNECT_ERROR;
-#endif
-
-  default:
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-}
-
-static CURLcode nss_init_sslver(SSLVersionRange *sslver,
-                                struct Curl_cfilter *cf,
-                                struct Curl_easy *data)
-{
-  struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
-  CURLcode result;
-  const long min = conn_config->version;
-  const long max = conn_config->version_max;
-  SSLVersionRange vrange;
-
-  switch(min) {
-  case CURL_SSLVERSION_TLSv1:
-  case CURL_SSLVERSION_DEFAULT:
-    /* Bump our minimum TLS version if NSS has stricter requirements. */
-    if(SSL_VersionRangeGetDefault(ssl_variant_stream, &vrange) != SECSuccess)
-      return CURLE_SSL_CONNECT_ERROR;
-    if(sslver->min < vrange.min)
-      sslver->min = vrange.min;
-    break;
-  default:
-    result = nss_sslver_from_curl(&sslver->min, min);
-    if(result) {
-      failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
-      return result;
-    }
-  }
-
-  switch(max) {
-  case CURL_SSLVERSION_MAX_NONE:
-  case CURL_SSLVERSION_MAX_DEFAULT:
-    break;
-  default:
-    result = nss_sslver_from_curl(&sslver->max, max >> 16);
-    if(result) {
-      failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
-      return result;
-    }
-  }
-
-  return CURLE_OK;
-}
-
-static CURLcode nss_fail_connect(struct Curl_cfilter *cf,
-                                 struct Curl_easy *data,
-                                 CURLcode curlerr)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-
-  DEBUGASSERT(backend);
-
-  if(is_nss_error(curlerr)) {
-    /* read NSPR error code */
-    PRErrorCode err = PR_GetError();
-    if(is_cc_error(err))
-      curlerr = CURLE_SSL_CERTPROBLEM;
-
-    /* print the error number and error string */
-    infof(data, "NSS error %d (%s)", err, nss_error_to_name(err));
-
-    /* print a human-readable message describing the error if available */
-    nss_print_error_message(data, err);
-  }
-
-  /* cleanup on connection failure */
-  Curl_llist_destroy(&backend->obj_list, NULL);
-
-  return curlerr;
-}
-
-/* Switch the SSL socket into blocking or non-blocking mode. */
-static CURLcode nss_set_blocking(struct Curl_cfilter *cf,
-                                 struct Curl_easy *data,
-                                 bool blocking)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  PRSocketOptionData sock_opt;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-
-  DEBUGASSERT(backend);
-
-  sock_opt.option = PR_SockOpt_Nonblocking;
-  sock_opt.value.non_blocking = !blocking;
-
-  if(PR_SetSocketOption(backend->handle, &sock_opt) != PR_SUCCESS)
-    return nss_fail_connect(cf, data, CURLE_SSL_CONNECT_ERROR);
-
-  return CURLE_OK;
-}
-
-static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
-                                  struct Curl_easy *data)
-{
-  PRFileDesc *model = NULL;
-  PRFileDesc *nspr_io = NULL;
-  PRFileDesc *nspr_io_stub = NULL;
-  PRBool ssl_no_cache;
-  PRBool ssl_cbc_random_iv;
-  curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
-  struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
-  struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
-  struct ssl_connect_data *connssl_next = cf_ssl_next?
-                                            cf_ssl_next->ctx : NULL;
-  CURLcode result;
-  bool second_layer = FALSE;
-  SSLVersionRange sslver_supported;
-  SSLVersionRange sslver = {
-    SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
-#ifdef SSL_LIBRARY_VERSION_TLS_1_3
-    SSL_LIBRARY_VERSION_TLS_1_3   /* max */
-#elif defined SSL_LIBRARY_VERSION_TLS_1_2
-    SSL_LIBRARY_VERSION_TLS_1_2
-#elif defined SSL_LIBRARY_VERSION_TLS_1_1
-    SSL_LIBRARY_VERSION_TLS_1_1
-#else
-    SSL_LIBRARY_VERSION_TLS_1_0
-#endif
-  };
-  const char *hostname = connssl->hostname;
-  char *snihost;
-
-  snihost = Curl_ssl_snihost(data, hostname, NULL);
-  if(!snihost) {
-    failf(data, "Failed to set SNI");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  DEBUGASSERT(backend);
-
-  backend->data = data;
-
-  /* list of all NSS objects we need to destroy in nss_do_close() */
-  Curl_llist_init(&backend->obj_list, nss_destroy_object);
-
-  PR_Lock(nss_initlock);
-  result = nss_setup(data);
-  if(result) {
-    PR_Unlock(nss_initlock);
-    goto error;
-  }
-
-  PK11_SetPasswordFunc(nss_get_password);
-
-  result = nss_load_module(&pem_module, pem_library, "PEM");
-  PR_Unlock(nss_initlock);
-  if(result == CURLE_FAILED_INIT)
-    infof(data, "WARNING: failed to load NSS PEM library %s. Using "
-                "OpenSSL PEM certificates will not work.", pem_library);
-  else if(result)
-    goto error;
-
-  result = CURLE_SSL_CONNECT_ERROR;
-
-  model = PR_NewTCPSocket();
-  if(!model)
-    goto error;
-  model = SSL_ImportFD(NULL, model);
-
-  if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
-    goto error;
-  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
-    goto error;
-  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
-    goto error;
-
-  /* do not use SSL cache if disabled or we are not going to verify peer */
-  ssl_no_cache = (ssl_config->primary.sessionid
-                  && conn_config->verifypeer) ? PR_FALSE : PR_TRUE;
-  if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
-    goto error;
-
-  /* enable/disable the requested SSL version(s) */
-  if(nss_init_sslver(&sslver, cf, data) != CURLE_OK)
-    goto error;
-  if(SSL_VersionRangeGetSupported(ssl_variant_stream,
-                                  &sslver_supported) != SECSuccess)
-    goto error;
-  if(sslver_supported.max < sslver.max && sslver_supported.max >= sslver.min) {
-    char *sslver_req_str, *sslver_supp_str;
-    sslver_req_str = nss_sslver_to_name(sslver.max);
-    sslver_supp_str = nss_sslver_to_name(sslver_supported.max);
-    if(sslver_req_str && sslver_supp_str)
-      infof(data, "Falling back from %s to max supported SSL version (%s)",
-            sslver_req_str, sslver_supp_str);
-    free(sslver_req_str);
-    free(sslver_supp_str);
-    sslver.max = sslver_supported.max;
-  }
-  if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
-    goto error;
-
-  ssl_cbc_random_iv = !ssl_config->enable_beast;
-#ifdef SSL_CBC_RANDOM_IV
-  /* unless the user explicitly asks to allow the protocol vulnerability, we
-     use the work-around */
-  if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess)
-    infof(data, "WARNING: failed to set SSL_CBC_RANDOM_IV = %d",
-          ssl_cbc_random_iv);
-#else
-  if(ssl_cbc_random_iv)
-    infof(data, "WARNING: support for SSL_CBC_RANDOM_IV not compiled in");
-#endif
-
-  if(conn_config->cipher_list) {
-    if(set_ciphers(data, model, conn_config->cipher_list) != SECSuccess) {
-      result = CURLE_SSL_CIPHER;
-      goto error;
-    }
-  }
-
-  if(!conn_config->verifypeer && conn_config->verifyhost)
-    infof(data, "WARNING: ignoring value of ssl.verifyhost");
-
-  /* bypass the default SSL_AuthCertificate() hook in case we do not want to
-   * verify peer */
-  if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, cf) != SECSuccess)
-    goto error;
-
-  /* not checked yet */
-  ssl_config->certverifyresult = 0;
-
-  if(SSL_BadCertHook(model, BadCertHandler, cf) != SECSuccess)
-    goto error;
-
-  if(SSL_HandshakeCallback(model, HandshakeCallback, cf) != SECSuccess)
-    goto error;
-
-  {
-    const CURLcode rv = nss_load_ca_certificates(cf, data);
-    if((rv == CURLE_SSL_CACERT_BADFILE) && !conn_config->verifypeer)
-      /* not a fatal error because we are not going to verify the peer */
-      infof(data, "WARNING: CA certificates failed to load");
-    else if(rv) {
-      result = rv;
-      goto error;
-    }
-  }
-
-  if(ssl_config->primary.CRLfile) {
-    const CURLcode rv = nss_load_crl(ssl_config->primary.CRLfile);
-    if(rv) {
-      result = rv;
-      goto error;
-    }
-    infof(data, "  CRLfile: %s", ssl_config->primary.CRLfile);
-  }
-
-  if(ssl_config->primary.clientcert) {
-    char *nickname = dup_nickname(data, ssl_config->primary.clientcert);
-    if(nickname) {
-      /* we are not going to use libnsspem.so to read the client cert */
-      backend->obj_clicert = NULL;
-    }
-    else {
-      CURLcode rv = cert_stuff(cf, data,
-                               ssl_config->primary.clientcert,
-                               ssl_config->key);
-      if(rv) {
-        /* failf() is already done in cert_stuff() */
-        result = rv;
-        goto error;
-      }
-    }
-
-    /* store the nickname for SelectClientCert() called during handshake */
-    backend->client_nickname = nickname;
-  }
-  else
-    backend->client_nickname = NULL;
-
-  if(SSL_GetClientAuthDataHook(model, SelectClientCert,
-                               (void *)connssl) != SECSuccess) {
-    result = CURLE_SSL_CERTPROBLEM;
-    goto error;
-  }
-
-  /* Is there an SSL filter "in front" of us or are we writing directly
-   * to the socket? */
-  if(connssl_next) {
-    struct nss_ssl_backend_data *backend_next =
-      (struct nss_ssl_backend_data *)connssl_next->backend;
-    /* The filter should be connected by now, with full handshake */
-    DEBUGASSERT(backend_next->handle);
-    DEBUGASSERT(ssl_connection_complete == connssl_next->state);
-    /* We tell our NSS instance to use do IO with the 'next' NSS
-    * instance. This NSS instance will take ownership of the next
-    * one, including its destruction. We therefore need to `disown`
-    * the next filter's handle, once import succeeds. */
-    nspr_io = backend->handle;
-    second_layer = TRUE;
-  }
-  else {
-    /* wrap OS file descriptor by NSPR's file descriptor abstraction */
-    nspr_io = PR_ImportTCPSocket(sockfd);
-    if(!nspr_io)
-      goto error;
-  }
-
-  /* create our own NSPR I/O layer */
-  nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
-  if(!nspr_io_stub) {
-    if(!second_layer)
-      PR_Close(nspr_io);
-    goto error;
-  }
-
-  /* make the per-connection data accessible from NSPR I/O callbacks */
-  nspr_io_stub->secret = (void *)connssl;
-
-  /* push our new layer to the NSPR I/O stack */
-  if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
-    if(!second_layer)
-      PR_Close(nspr_io);
-    PR_Close(nspr_io_stub);
-    goto error;
-  }
-
-  /* import our model socket onto the current I/O stack */
-  backend->handle = SSL_ImportFD(model, nspr_io);
-  if(!backend->handle) {
-    if(!second_layer)
-      PR_Close(nspr_io);
-    goto error;
-  }
-
-  PR_Close(model); /* We don't need this any more */
-  model = NULL;
-  if(connssl_next) { /* steal the NSS handle we just imported successfully */
-    struct nss_ssl_backend_data *backend_next =
-      (struct nss_ssl_backend_data *)connssl_next->backend;
-    backend_next->handle = NULL;
-  }
-
-  /* This is the password associated with the cert that we're using */
-  if(ssl_config->key_passwd) {
-    SSL_SetPKCS11PinArg(backend->handle, ssl_config->key_passwd);
-  }
-
-#ifdef SSL_ENABLE_OCSP_STAPLING
-  if(conn_config->verifystatus) {
-    if(SSL_OptionSet(backend->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
-        != SECSuccess)
-      goto error;
-  }
-#endif
-
-#ifdef SSL_ENABLE_ALPN
-  if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN,
-                   connssl->alpn ? PR_TRUE : PR_FALSE)
-      != SECSuccess)
-    goto error;
-#endif
-
-#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
-  if(data->set.ssl.falsestart) {
-    if(SSL_OptionSet(backend->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
-        != SECSuccess)
-      goto error;
-
-    if(SSL_SetCanFalseStartCallback(backend->handle, CanFalseStartCallback,
-        data) != SECSuccess)
-      goto error;
-  }
-#endif
-
-#if defined(SSL_ENABLE_ALPN)
-  if(connssl->alpn) {
-    struct alpn_proto_buf proto;
-
-    result = Curl_alpn_to_proto_buf(&proto, connssl->alpn);
-    if(result || SSL_SetNextProtoNego(backend->handle, proto.data, proto.len)
-                   != SECSuccess) {
-      failf(data, "Error setting ALPN");
-      goto error;
-    }
-    Curl_alpn_to_proto_str(&proto, connssl->alpn);
-    infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
-  }
-#endif
-
-
-  /* Force handshake on next I/O */
-  if(SSL_ResetHandshake(backend->handle, /* asServer */ PR_FALSE)
-      != SECSuccess)
-    goto error;
-
-  /* propagate hostname to the TLS layer */
-  if(SSL_SetURL(backend->handle, snihost) != SECSuccess)
-    goto error;
-
-  /* prevent NSS from re-using the session for a different hostname */
-  if(SSL_SetSockPeerID(backend->handle, snihost) != SECSuccess)
-    goto error;
-
-  return CURLE_OK;
-
-error:
-  if(model)
-    PR_Close(model);
-
-  return nss_fail_connect(cf, data, result);
-}
-
-static CURLcode nss_do_connect(struct Curl_cfilter *cf,
-                               struct Curl_easy *data)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
-  struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
-  CURLcode result = CURLE_SSL_CONNECT_ERROR;
-  PRUint32 timeout;
-
-  /* check timeout situation */
-  const timediff_t time_left = Curl_timeleft(data, NULL, TRUE);
-  if(time_left < 0) {
-    failf(data, "timed out before SSL handshake");
-    result = CURLE_OPERATION_TIMEDOUT;
-    goto error;
-  }
-
-  DEBUGASSERT(backend);
-
-  /* Force the handshake now */
-  timeout = PR_MillisecondsToInterval((PRUint32) time_left);
-  if(SSL_ForceHandshakeWithTimeout(backend->handle, timeout) != SECSuccess) {
-    if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
-      /* blocking direction is updated by nss_update_connecting_state() */
-      return CURLE_AGAIN;
-    else if(ssl_config->certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
-      result = CURLE_PEER_FAILED_VERIFICATION;
-    else if(ssl_config->certverifyresult)
-      result = CURLE_PEER_FAILED_VERIFICATION;
-    goto error;
-  }
-
-  result = display_conn_info(data, backend->handle);
-  if(result)
-    goto error;
-
-  if(conn_config->issuercert) {
-    SECStatus ret = SECFailure;
-    char *nickname = dup_nickname(data, conn_config->issuercert);
-    if(nickname) {
-      /* we support only nicknames in case of issuercert for now */
-      ret = check_issuer_cert(backend->handle, nickname);
-      free(nickname);
-    }
-
-    if(SECFailure == ret) {
-      infof(data, "SSL certificate issuer check failed");
-      result = CURLE_SSL_ISSUER_ERROR;
-      goto error;
-    }
-    else {
-      infof(data, "SSL certificate issuer check ok");
-    }
-  }
-
-  result = cmp_peer_pubkey(connssl,  Curl_ssl_cf_is_proxy(cf)?
-                           data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
-                           data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
-  if(result)
-    /* status already printed */
-    goto error;
-
-  return CURLE_OK;
-
-error:
-  return nss_fail_connect(cf, data, result);
-}
-
-static CURLcode nss_connect_common(struct Curl_cfilter *cf,
-                                   struct Curl_easy *data,
-                                   bool *done)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  const bool blocking = (done == NULL);
-  CURLcode result;
-
-  if(connssl->state == ssl_connection_complete) {
-    if(!blocking)
-      *done = TRUE;
-    return CURLE_OK;
-  }
-
-  if(connssl->connecting_state == ssl_connect_1) {
-    result = nss_setup_connect(cf, data);
-    if(result)
-      /* we do not expect CURLE_AGAIN from nss_setup_connect() */
-      return result;
-
-    connssl->connecting_state = ssl_connect_2;
-  }
-
-  /* enable/disable blocking mode before handshake */
-  result = nss_set_blocking(cf, data, blocking);
-  if(result)
-    return result;
-
-  result = nss_do_connect(cf, data);
-  switch(result) {
-  case CURLE_OK:
-    break;
-  case CURLE_AGAIN:
-    /* CURLE_AGAIN in non-blocking mode is not an error */
-    if(!blocking)
-      return CURLE_OK;
-    else
-      return result;
-  default:
-    return result;
-  }
-
-  if(blocking) {
-    /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
-    result = nss_set_blocking(cf, data, /* blocking */ FALSE);
-    if(result)
-      return result;
-  }
-  else
-    /* signal completed SSL handshake */
-    *done = TRUE;
-
-  connssl->state = ssl_connection_complete;
-
-  /* ssl_connect_done is never used outside, go back to the initial state */
-  connssl->connecting_state = ssl_connect_1;
-
-  return CURLE_OK;
-}
-
-static CURLcode nss_connect(struct Curl_cfilter *cf,
-                            struct Curl_easy *data)
-{
-  return nss_connect_common(cf, data, /* blocking */ NULL);
-}
-
-static CURLcode nss_connect_nonblocking(struct Curl_cfilter *cf,
-                                        struct Curl_easy *data,
-                                        bool *done)
-{
-  return nss_connect_common(cf, data, done);
-}
-
-static ssize_t nss_send(struct Curl_cfilter *cf,
-                        struct Curl_easy *data,    /* transfer */
-                        const void *mem,           /* send this data */
-                        size_t len,                /* amount to write */
-                        CURLcode *curlcode)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  ssize_t rc;
-
-  (void)data;
-  DEBUGASSERT(backend);
-
-  /* The SelectClientCert() hook uses this for infof() and failf() but the
-     handle stored in nss_setup_connect() could have already been freed. */
-  backend->data = data;
-
-  rc = PR_Send(backend->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
-  if(rc < 0) {
-    PRInt32 err = PR_GetError();
-    if(err == PR_WOULD_BLOCK_ERROR)
-      *curlcode = CURLE_AGAIN;
-    else {
-      /* print the error number and error string */
-      const char *err_name = nss_error_to_name(err);
-      infof(data, "SSL write: error %d (%s)", err, err_name);
-
-      /* print a human-readable message describing the error if available */
-      nss_print_error_message(data, err);
-
-      *curlcode = (is_cc_error(err))
-        ? CURLE_SSL_CERTPROBLEM
-        : CURLE_SEND_ERROR;
-    }
-
-    return -1;
-  }
-
-  return rc; /* number of bytes */
-}
-
-static bool
-nss_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  PRFileDesc *fd = backend->handle->lower;
-  char buf;
-
-  (void) data;
-
-  /* Returns true in case of error to force reading. */
-  return PR_Recv(fd, (void *) &buf, 1, PR_MSG_PEEK, PR_INTERVAL_NO_WAIT) != 0;
-}
-
-static ssize_t nss_recv(struct Curl_cfilter *cf,
-                        struct Curl_easy *data,    /* transfer */
-                        char *buf,             /* store read data here */
-                        size_t buffersize,     /* max amount to read */
-                        CURLcode *curlcode)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  ssize_t nread;
-
-  (void)data;
-  DEBUGASSERT(backend);
-
-  /* The SelectClientCert() hook uses this for infof() and failf() but the
-     handle stored in nss_setup_connect() could have already been freed. */
-  backend->data = data;
-
-  nread = PR_Recv(backend->handle, buf, (int)buffersize, 0,
-                  PR_INTERVAL_NO_WAIT);
-  if(nread < 0) {
-    /* failed SSL read */
-    PRInt32 err = PR_GetError();
-
-    if(err == PR_WOULD_BLOCK_ERROR)
-      *curlcode = CURLE_AGAIN;
-    else {
-      /* print the error number and error string */
-      const char *err_name = nss_error_to_name(err);
-      infof(data, "SSL read: errno %d (%s)", err, err_name);
-
-      /* print a human-readable message describing the error if available */
-      nss_print_error_message(data, err);
-
-      *curlcode = (is_cc_error(err))
-        ? CURLE_SSL_CERTPROBLEM
-        : CURLE_RECV_ERROR;
-    }
-
-    return -1;
-  }
-
-  return nread;
-}
-
-static size_t nss_version(char *buffer, size_t size)
-{
-  return msnprintf(buffer, size, "NSS/%s", NSS_GetVersion());
-}
-
-/* data might be NULL */
-static int Curl_nss_seed(struct Curl_easy *data)
-{
-  /* make sure that NSS is initialized */
-  return !!Curl_nss_force_init(data);
-}
-
-/* data might be NULL */
-static CURLcode nss_random(struct Curl_easy *data,
-                           unsigned char *entropy,
-                           size_t length)
-{
-  Curl_nss_seed(data);  /* Initiate the seed if not already done */
-
-  if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length)))
-    /* signal a failure */
-    return CURLE_FAILED_INIT;
-
-  return CURLE_OK;
-}
-
-static CURLcode nss_sha256sum(const unsigned char *tmp, /* input */
-                              size_t tmplen,
-                              unsigned char *sha256sum, /* output */
-                              size_t sha256len)
-{
-  PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
-  unsigned int SHA256out;
-
-  if(!SHA256pw)
-    return CURLE_NOT_BUILT_IN;
-
-  PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
-  PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
-  PK11_DestroyContext(SHA256pw, PR_TRUE);
-
-  return CURLE_OK;
-}
-
-static bool nss_cert_status_request(void)
-{
-#ifdef SSL_ENABLE_OCSP_STAPLING
-  return TRUE;
-#else
-  return FALSE;
-#endif
-}
-
-static bool nss_false_start(void)
-{
-#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
-  return TRUE;
-#else
-  return FALSE;
-#endif
-}
-
-static void *nss_get_internals(struct ssl_connect_data *connssl,
-                               CURLINFO info UNUSED_PARAM)
-{
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-  (void)info;
-  DEBUGASSERT(backend);
-  return backend->handle;
-}
-
-static bool nss_attach_data(struct Curl_cfilter *cf,
-                            struct Curl_easy *data)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-
-  if(!backend->data)
-    backend->data = data;
-  return TRUE;
-}
-
-static void nss_detach_data(struct Curl_cfilter *cf,
-                            struct Curl_easy *data)
-{
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct nss_ssl_backend_data *backend =
-    (struct nss_ssl_backend_data *)connssl->backend;
-
-  if(backend->data == data)
-    backend->data = NULL;
-}
-
-const struct Curl_ssl Curl_ssl_nss = {
-  { CURLSSLBACKEND_NSS, "nss" }, /* info */
-
-  SSLSUPP_CA_PATH |
-  SSLSUPP_CERTINFO |
-  SSLSUPP_PINNEDPUBKEY |
-  SSLSUPP_HTTPS_PROXY,
-
-  sizeof(struct nss_ssl_backend_data),
-
-  nss_init,                     /* init */
-  nss_cleanup,                  /* cleanup */
-  nss_version,                  /* version */
-  Curl_none_check_cxn,          /* check_cxn */
-  /* NSS has no shutdown function provided and thus always fail */
-  Curl_none_shutdown,           /* shutdown */
-  nss_data_pending,             /* data_pending */
-  nss_random,                   /* random */
-  nss_cert_status_request,      /* cert_status_request */
-  nss_connect,                  /* connect */
-  nss_connect_nonblocking,      /* connect_nonblocking */
-  Curl_ssl_get_select_socks,             /* getsock */
-  nss_get_internals,            /* get_internals */
-  nss_close,                    /* close_one */
-  Curl_none_close_all,          /* close_all */
-  /* NSS has its own session ID cache */
-  Curl_none_session_free,       /* session_free */
-  Curl_none_set_engine,         /* set_engine */
-  Curl_none_set_engine_default, /* set_engine_default */
-  Curl_none_engines_list,       /* engines_list */
-  nss_false_start,              /* false_start */
-  nss_sha256sum,                /* sha256sum */
-  nss_attach_data,              /* associate_connection */
-  nss_detach_data,              /* disassociate_connection */
-  NULL,                         /* free_multi_ssl_backend_data */
-  nss_recv,                     /* recv decrypted data */
-  nss_send,                     /* send data to encrypt */
-};
-
-#endif /* USE_NSS */

+ 0 - 41
lib/vtls/nssg.h

@@ -1,41 +0,0 @@
-#ifndef HEADER_CURL_NSSG_H
-#define HEADER_CURL_NSSG_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 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
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#ifdef USE_NSS
-/*
- * This header should only be needed to get included by vtls.c and nss.c
- */
-
-#include "urldata.h"
-
-/* initialize NSS library if not already */
-CURLcode Curl_nss_force_init(struct Curl_easy *data);
-
-extern const struct Curl_ssl Curl_ssl_nss;
-
-#endif /* USE_NSS */
-#endif /* HEADER_CURL_NSSG_H */

+ 1 - 1
lib/vtls/sectransp.c

@@ -1293,7 +1293,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
 
 /* This code was borrowed from nss.c, with some modifications:
  * Determine whether the nickname passed in is a filename that needs to
- * be loaded as a PEM or a regular NSS nickname.
+ * be loaded as a PEM or a nickname.
  *
  * returns 1 for a file
  * returns 0 for not a file

+ 0 - 5
lib/vtls/vtls.c

@@ -1244,8 +1244,6 @@ const struct Curl_ssl *Curl_ssl =
   &Curl_ssl_gskit;
 #elif defined(USE_MBEDTLS)
   &Curl_ssl_mbedtls;
-#elif defined(USE_NSS)
-  &Curl_ssl_nss;
 #elif defined(USE_RUSTLS)
   &Curl_ssl_rustls;
 #elif defined(USE_OPENSSL)
@@ -1274,9 +1272,6 @@ static const struct Curl_ssl *available_backends[] = {
 #if defined(USE_MBEDTLS)
   &Curl_ssl_mbedtls,
 #endif
-#if defined(USE_NSS)
-  &Curl_ssl_nss,
-#endif
 #if defined(USE_OPENSSL)
   &Curl_ssl_openssl,
 #endif

+ 0 - 1
lib/vtls/vtls_int.h

@@ -217,7 +217,6 @@ CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf,
 
 #include "openssl.h"        /* OpenSSL versions */
 #include "gtls.h"           /* GnuTLS versions */
-#include "nssg.h"           /* NSS versions */
 #include "gskit.h"          /* Global Secure ToolKit versions */
 #include "wolfssl.h"        /* wolfSSL versions */
 #include "schannel.h"       /* Schannel SSPI version */

+ 6 - 6
lib/vtls/x509asn1.c

@@ -24,15 +24,15 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) ||    \
-  defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
+#if defined(USE_GSKIT) || defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
+  defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
 
 #if defined(USE_GSKIT) || defined(USE_WOLFSSL) || defined(USE_SCHANNEL)
 #define WANT_PARSEX509 /* uses Curl_parseX509() */
 #endif
 
-#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) ||    \
-  defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
+#if defined(USE_GSKIT) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
+  defined(USE_SECTRANSP)
 #define WANT_EXTRACT_CERTINFO /* uses Curl_extract_certinfo() */
 #define WANT_PARSEX509 /* ... uses Curl_parseX509() */
 #endif
@@ -1261,8 +1261,8 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
 
 #endif /* WANT_EXTRACT_CERTINFO */
 
-#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL
-        * or USE_SECTRANSP */
+#endif /* USE_GSKIT or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL * or
+          USE_SECTRANSP */
 
 #ifdef WANT_VERIFYHOST
 

+ 3 - 3
lib/vtls/x509asn1.h

@@ -27,8 +27,8 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
-    defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
+#if defined(USE_GSKIT) || defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
+  defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
 
 #include "cfilters.h"
 #include "urldata.h"
@@ -76,6 +76,6 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum,
                                const char *beg, const char *end);
 CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data,
                          const char *beg, const char *end);
-#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL
+#endif /* USE_GSKIT or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL
         * or USE_SECTRANSP */
 #endif /* HEADER_CURL_X509ASN1_H */

+ 0 - 144
m4/curl-nss.m4

@@ -1,144 +0,0 @@
-#***************************************************************************
-#                                  _   _ ____  _
-#  Project                     ___| | | |  _ \| |
-#                             / __| | | | |_) | |
-#                            | (__| |_| |  _ <| |___
-#                             \___|\___/|_| \_\_____|
-#
-# Copyright (C) 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
-# are also available at https://curl.se/docs/copyright.html.
-#
-# You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# copies of the Software, and permit persons to whom the Software is
-# furnished to do so, under the terms of the COPYING file.
-#
-# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# KIND, either express or implied.
-#
-# SPDX-License-Identifier: curl
-#
-#***************************************************************************
-
-AC_DEFUN([CURL_WITH_NSS], [
-if test "x$OPT_NSS" != xno; then
-  ssl_msg=
-
-  if test X"$OPT_NSS" != Xno; then
-
-    addld=""
-    addlib=""
-    addcflags=""
-    nssprefix=""
-    version=""
-
-    if test "x$OPT_NSS" = "xyes"; then
-
-      CURL_CHECK_PKGCONFIG(nss)
-
-      if test "$PKGCONFIG" != "no" ; then
-        addlib=`$PKGCONFIG --libs nss`
-        addcflags=`$PKGCONFIG --cflags nss`
-        version=`$PKGCONFIG --modversion nss`
-        nssprefix=`$PKGCONFIG --variable=prefix nss`
-      else
-        dnl Without pkg-config, we check for nss-config
-
-        check=`nss-config --version 2>/dev/null`
-        if test -n "$check"; then
-          addlib=`nss-config --libs`
-          addcflags=`nss-config --cflags`
-          version=`nss-config --version`
-          nssprefix=`nss-config --prefix`
-        else
-          addlib="-lnss3"
-          addcflags=""
-          version="unknown"
-        fi
-      fi
-    else
-      NSS_PCDIR="$OPT_NSS/lib/pkgconfig"
-      if test -f "$NSS_PCDIR/nss.pc"; then
-        CURL_CHECK_PKGCONFIG(nss, [$NSS_PCDIR])
-        if test "$PKGCONFIG" != "no" ; then
-          addld=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --libs-only-L nss`
-          addlib=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --libs-only-l nss`
-          addcflags=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --cflags nss`
-          version=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --modversion nss`
-          nssprefix=`CURL_EXPORT_PCDIR([$NSS_PCDIR]) $PKGCONFIG --variable=prefix nss`
-        fi
-      fi
-    fi
-
-    if test -z "$addlib"; then
-      # Without pkg-config, we'll kludge in some defaults
-      AC_MSG_WARN([Using hard-wired libraries and compilation flags for NSS.])
-      addld="-L$OPT_NSS/lib"
-      addlib="-lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4"
-      addcflags="-I$OPT_NSS/include"
-      version="unknown"
-      nssprefix=$OPT_NSS
-    fi
-
-    CLEANLDFLAGS="$LDFLAGS"
-    CLEANLIBS="$LIBS"
-    CLEANCPPFLAGS="$CPPFLAGS"
-
-    LDFLAGS="$addld $LDFLAGS"
-    LIBS="$addlib $LIBS"
-    if test "$addcflags" != "-I/usr/include"; then
-       CPPFLAGS="$CPPFLAGS $addcflags"
-    fi
-
-    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])
-     USE_NSS="yes"
-     NSS_ENABLED=1
-     ssl_msg="NSS"
-     test nss != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes
-     ],
-     [
-       LDFLAGS="$CLEANLDFLAGS"
-       LIBS="$CLEANLIBS"
-       CPPFLAGS="$CLEANCPPFLAGS"
-     ])
-
-    if test "x$USE_NSS" = "xyes"; then
-      AC_MSG_NOTICE([detected NSS version $version])
-
-      dnl PK11_CreateManagedGenericObject() was introduced in NSS 3.34 because
-      dnl PK11_DestroyGenericObject() does not release resources allocated by
-      dnl PK11_CreateGenericObject() early enough.
-      AC_CHECK_FUNC(PK11_CreateManagedGenericObject,
-        [
-          AC_DEFINE(HAVE_PK11_CREATEMANAGEDGENERICOBJECT, 1,
-                    [if you have the PK11_CreateManagedGenericObject function])
-        ])
-
-      dnl needed when linking the curl tool without USE_EXPLICIT_LIB_DEPS
-      NSS_LIBS=$addlib
-      AC_SUBST([NSS_LIBS])
-
-      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 CURL_LIBRARY_PATH to prevent further configure tests to fail
-      dnl due to this
-      if test "x$cross_compiling" != "xyes"; then
-        CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$nssprefix/lib$libsuff"
-        export CURL_LIBRARY_PATH
-        AC_MSG_NOTICE([Added $nssprefix/lib$libsuff to CURL_LIBRARY_PATH])
-      fi
-
-    fi dnl NSS found
-
-  fi dnl NSS not disabled
-
-  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
-fi
-
-])

+ 0 - 3
packages/vms/generate_config_vms_h_curl.com

@@ -336,9 +336,6 @@ $write cvh "#endif"
 $write cvh "#ifdef USE_NGHTTP2"
 $write cvh "#undef USE_NGHTTP2"
 $write cvh "#endif"
-$write cvh "#ifdef USE_NSS"
-$write cvh "#undef USE_NSS"
-$write cvh "#endif"
 $write cvh "#ifdef USE_OPENLDAP"
 $write cvh "#undef USE_OPENLDAP"
 $write cvh "#endif"

+ 1 - 1
src/Makefile.am

@@ -69,7 +69,7 @@ LIBS = $(BLANK_AT_MAKETIME)
 if USE_EXPLICIT_LIB_DEPS
 curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
 else
-curl_LDADD = $(top_builddir)/lib/libcurl.la @NSS_LIBS@ @SSL_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@
+curl_LDADD = $(top_builddir)/lib/libcurl.la @SSL_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@
 endif
 
 # if unit tests are enabled, build a static library to link them with

+ 0 - 13
src/tool_main.c

@@ -37,11 +37,6 @@
 #include <fcntl.h>
 #endif
 
-#ifdef USE_NSS
-#include <nspr.h>
-#include <plarenas.h>
-#endif
-
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
 #include "curlx.h"
@@ -213,14 +208,6 @@ static void main_free(struct GlobalConfig *config)
   /* Cleanup the easy handle */
   /* Main cleanup */
   curl_global_cleanup();
-#ifdef USE_NSS
-  if(PR_Initialized()) {
-    /* prevent valgrind from reporting still reachable mem from NSPR arenas */
-    PL_ArenaFinish();
-    /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */
-    PR_Cleanup();
-  }
-#endif
   free_globalconfig(config);
 
   /* Free the config structures */

+ 0 - 1
tests/FILEFORMAT.md

@@ -439,7 +439,6 @@ Features testable here are:
 - `netrc`
 - `nghttpx`
 - `nghttpx-h3`
-- `NSS`
 - `NTLM`
 - `NTLM_WB`
 - `OpenSSL`

+ 2 - 2
tests/libtest/Makefile.am

@@ -52,8 +52,8 @@ if USE_EXPLICIT_LIB_DEPS
 SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
 TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
 else
-SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@ @NSS_LIBS@
-TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@ @NSS_LIBS@
+SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@
+TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@
 endif
 
 # Dependencies (may need to be overridden)

+ 0 - 10
tests/libtest/first.c

@@ -35,10 +35,6 @@
 #  include <fcntl.h> /* for setmode() */
 #endif
 
-#ifdef USE_NSS
-#include <nspr.h>
-#endif
-
 #ifdef CURLDEBUG
 #  define MEMDEBUG_NODEFINES
 #  include "memdebug.h"
@@ -177,12 +173,6 @@ int main(int argc, char **argv)
 
   result = test(URL);
 
-#ifdef USE_NSS
-  if(PR_Initialized())
-    /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */
-    PR_Cleanup();
-#endif
-
 #ifdef WIN32
   /* flush buffers of all streams regardless of mode */
   _flushall();

+ 0 - 4
tests/runtests.pl

@@ -541,10 +541,6 @@ sub checksystemfeatures {
            elsif ($libcurl =~ /\srustls-ffi\b/i) {
                $feature{"rustls"} = 1;
            }
-           elsif ($libcurl =~ /\snss\b/i) {
-               $feature{"NSS"} = 1;
-               $feature{"SSLpinning"} = 1;
-           }
            elsif ($libcurl =~ /\swolfssl\b/i) {
                $feature{"wolfssl"} = 1;
                $feature{"SSLpinning"} = 1;

+ 1 - 1
tests/unit/Makefile.am

@@ -47,7 +47,7 @@ LIBS = $(BLANK_AT_MAKETIME)
 
 LDADD = $(top_builddir)/src/libcurltool.la   \
         $(top_builddir)/lib/libcurlu.la      \
-        @LDFLAGS@ @LIBCURL_LIBS@ @NSS_LIBS@
+        @LDFLAGS@ @LIBCURL_LIBS@
 
 AM_CPPFLAGS += -DCURL_STATICLIB -DUNITTESTS
 

+ 2 - 2
tests/unit/unit1651.c

@@ -34,8 +34,8 @@ static void unit_stop(void)
 {
 
 }
-#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) ||    \
-  defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
+#if defined(USE_GSKIT) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
+  defined(USE_SECTRANSP)
 
 /* cert captured from gdb when connecting to curl.se on October 26
    2018 */