Resolves: #1445153 - switch the TLS backend back to OpenSSL

This commit is contained in:
Kamil Dudka 2017-04-27 10:42:34 +02:00
parent 9549974a4c
commit 3be7c46fde
3 changed files with 6 additions and 342 deletions

View File

@ -1,42 +0,0 @@
From ba1da47aa5080a73742ca9bc7c22ce2a703a3925 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 24 Apr 2017 15:01:04 +0200
Subject: [PATCH] nss: do not leak PKCS #11 slot while loading a key
It could prevent nss-pem from being unloaded later on.
Bug: https://bugzilla.redhat.com/1444860
Upstream-commit: c8ea86f377a2f341db635ec96f99314023b5a8f3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/vtls/nss.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 89a16d3..099f364 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -581,7 +581,7 @@ fail:
static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
char *key_file)
{
- PK11SlotInfo *slot;
+ PK11SlotInfo *slot, *tmp;
SECStatus status;
CURLcode result;
struct ssl_connect_data *ssl = conn->ssl;
@@ -600,7 +600,9 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
return CURLE_SSL_CERTPROBLEM;
/* This will force the token to be seen as re-inserted */
- SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+ tmp = SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+ if(tmp)
+ PK11_FreeSlot(tmp);
PK11_IsPresent(slot);
status = PK11_Authenticate(slot, PR_TRUE, SSL_SET_OPTION(key_passwd));
--
2.9.3

View File

@ -1,285 +0,0 @@
From 50582c5be1a613ee1d212855a8945b4c8ef8950f Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 10 Apr 2017 17:05:05 +0200
Subject: [PATCH 1/2] nss: factorize out nss_{un,}load_module to separate fncs
No change of behavior is intended by this commit.
Upstream-commit: fab3d1ec650e17fd15cf8b6d4ffa5bfd523501dc
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/vtls/nss.c | 83 +++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 56 insertions(+), 27 deletions(-)
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 099f364..6b8f8c0 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -201,7 +201,7 @@ static const cipher_s cipherlist[] = {
};
static const char *pem_library = "libnsspem.so";
-static SECMODModule *mod = NULL;
+static SECMODModule *pem_module = NULL;
/* NSPR I/O layer we use to detect blocking direction during SSL handshake */
static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
@@ -600,7 +600,7 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
return CURLE_SSL_CERTPROBLEM;
/* This will force the token to be seen as re-inserted */
- tmp = SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+ tmp = SECMOD_WaitForAnyTokenEvent(pem_module, 0, 0);
if(tmp)
PK11_FreeSlot(tmp);
PK11_IsPresent(slot);
@@ -1180,6 +1180,50 @@ static PRStatus nspr_io_close(PRFileDesc *fd)
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)
{
@@ -1327,10 +1371,7 @@ void Curl_nss_cleanup(void)
* the certificates. */
SSL_ClearSessionCache();
- if(mod && SECSuccess == SECMOD_UnloadUserModule(mod)) {
- SECMOD_DestroyModule(mod);
- mod = NULL;
- }
+ nss_unload_module(&pem_module);
NSS_ShutdownContext(nss_context);
nss_context = NULL;
}
@@ -1685,29 +1726,17 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
goto error;
}
- result = CURLE_SSL_CONNECT_ERROR;
-
- if(!mod) {
- char *configstring = aprintf("library=%s name=PEM", pem_library);
- if(!configstring) {
- PR_Unlock(nss_initlock);
- goto error;
- }
- mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
- free(configstring);
-
- if(!mod || !mod->loaded) {
- if(mod) {
- SECMOD_DestroyModule(mod);
- mod = NULL;
- }
- infof(data, "WARNING: failed to load NSS PEM library %s. Using "
- "OpenSSL PEM certificates will not work.\n", pem_library);
- }
- }
-
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.\n", pem_library);
+ else if(result)
+ goto error;
+
+ result = CURLE_SSL_CONNECT_ERROR;
model = PR_NewTCPSocket();
if(!model)
--
2.9.3
From cf6f9017f0e144ad510fd5913b44b22a2146dd4b Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 10 Apr 2017 17:40:30 +0200
Subject: [PATCH 2/2] nss: load libnssckbi.so if no other trust is specified
The module contains a more comprehensive set of trust information than
supported by nss-pem, because libnssckbi.so also includes information
about distrusted certificates.
Reviewed-by: Kai Engert
Closes #1414
Upstream-commit: e3e8d0204b72509cfd63d97a159d1ac3fdea703b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/libcurl/opts/CURLOPT_CAINFO.3 | 5 ++++
lib/vtls/nss.c | 51 ++++++++++++++++++++++++++++++++------
2 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/docs/libcurl/opts/CURLOPT_CAINFO.3 b/docs/libcurl/opts/CURLOPT_CAINFO.3
index 91b7e23..85436c3 100644
--- a/docs/libcurl/opts/CURLOPT_CAINFO.3
+++ b/docs/libcurl/opts/CURLOPT_CAINFO.3
@@ -41,6 +41,11 @@ 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 only) If curl is built against Secure Transport, then this
option is supported for backward compatibility with other SSL engines, but it
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 6b8f8c0..62665e7 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -81,6 +81,7 @@
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;
@@ -203,6 +204,9 @@ static const cipher_s cipherlist[] = {
static const char *pem_library = "libnsspem.so";
static SECMODModule *pem_module = NULL;
+static const char *trust_library = "libnssckbi.so";
+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;
@@ -1333,6 +1337,7 @@ int Curl_nss_init(void)
nss_initlock = PR_NewLock();
nss_crllock = PR_NewLock();
nss_findslot_lock = PR_NewLock();
+ nss_trustload_lock = PR_NewLock();
}
/* We will actually initialize NSS later */
@@ -1372,6 +1377,7 @@ void Curl_nss_cleanup(void)
SSL_ClearSessionCache();
nss_unload_module(&pem_module);
+ nss_unload_module(&trust_module);
NSS_ShutdownContext(nss_context);
nss_context = NULL;
}
@@ -1384,6 +1390,7 @@ void Curl_nss_cleanup(void)
PR_DestroyLock(nss_initlock);
PR_DestroyLock(nss_crllock);
PR_DestroyLock(nss_findslot_lock);
+ PR_DestroyLock(nss_trustload_lock);
nss_initlock = NULL;
initialized = 0;
@@ -1505,12 +1512,44 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
struct Curl_easy *data = conn->data;
const char *cafile = SSL_CONN_CONFIG(CAfile);
const char *capath = SSL_CONN_CONFIG(CApath);
+ bool use_trust_module;
+ CURLcode result = CURLE_OK;
- if(cafile) {
- CURLcode result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
- if(result)
- return result;
+ /* treat empty string as unset */
+ if(cafile && !cafile[0])
+ cafile = NULL;
+ if(capath && !capath[0])
+ capath = NULL;
+
+ infof(data, " CAfile: %s\n CApath: %s\n",
+ cafile ? cafile : "none",
+ 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\n", (result) ? "failed to load" : "loaded",
+ trust_library);
+ if(result == CURLE_FAILED_INIT)
+ /* make the error non-fatal if we are not going to verify peer */
+ result = CURLE_SSL_CACERT_BADFILE;
}
+ else if(!use_trust_module && trust_module) {
+ /* libnssckbi.so not needed but already loaded --> unload it! */
+ infof(data, "unloading %s\n", trust_library);
+ nss_unload_module(&trust_module);
+ }
+ PR_Unlock(nss_trustload_lock);
+
+ if(cafile)
+ result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
+
+ if(result)
+ return result;
if(capath) {
struct_stat st;
@@ -1544,10 +1583,6 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath);
}
- infof(data, " CAfile: %s\n CApath: %s\n",
- cafile ? cafile : "none",
- capath ? capath : "none");
-
return CURLE_OK;
}
--
2.9.3

View File

@ -1,17 +1,11 @@
Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
Name: curl Name: curl
Version: 7.54.0 Version: 7.54.0
Release: 2%{?dist} Release: 3%{?dist}
License: MIT License: MIT
Group: Applications/Internet Group: Applications/Internet
Source: https://curl.haxx.se/download/%{name}-%{version}.tar.lzma Source: https://curl.haxx.se/download/%{name}-%{version}.tar.lzma
# nss: do not leak PKCS #11 slot while loading a key (#1444860)
Patch1: 0001-curl-7.54.0-nss-pem-slot-leak.patch
# nss: use libnssckbi.so as the default source of trust
Patch2: 0002-curl-7.54.0-libnssckbi.patch
# patch making libcurl multilib ready # patch making libcurl multilib ready
Patch101: 0101-curl-7.32.0-multilib.patch Patch101: 0101-curl-7.32.0-multilib.patch
@ -33,10 +27,10 @@ BuildRequires: libnghttp2-devel
BuildRequires: libpsl-devel BuildRequires: libpsl-devel
BuildRequires: libssh2-devel BuildRequires: libssh2-devel
BuildRequires: multilib-rpm-config BuildRequires: multilib-rpm-config
BuildRequires: nss-devel
BuildRequires: openldap-devel BuildRequires: openldap-devel
BuildRequires: openssh-clients BuildRequires: openssh-clients
BuildRequires: openssh-server BuildRequires: openssh-server
BuildRequires: openssl-devel
BuildRequires: pkgconfig BuildRequires: pkgconfig
BuildRequires: python BuildRequires: python
BuildRequires: stunnel BuildRequires: stunnel
@ -89,10 +83,6 @@ Summary: A library for getting files from web servers
Group: Development/Libraries Group: Development/Libraries
Requires: libssh2%{?_isa} >= %{libssh2_version} Requires: libssh2%{?_isa} >= %{libssh2_version}
# libnsspem.so is no longer included in the nss package (#1347336)
BuildRequires: nss-pem
Requires: nss-pem%{?_isa}
%description -n libcurl %description -n libcurl
libcurl is a free and easy-to-use client-side URL transfer library, supporting libcurl is a free and easy-to-use client-side URL transfer library, supporting
FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS, FILE, IMAP, FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS, FILE, IMAP,
@ -144,8 +134,6 @@ be installed.
%setup -q %setup -q
# upstream patches # upstream patches
%patch1 -p1
%patch2 -p1
# Fedora patches # Fedora patches
%patch101 -p1 %patch101 -p1
@ -179,7 +167,7 @@ export common_configure_opts=" \
--enable-threaded-resolver \ --enable-threaded-resolver \
--with-gssapi \ --with-gssapi \
--with-nghttp2 \ --with-nghttp2 \
--without-ssl --with-nss --without-ca-bundle" --with-ssl --with-ca-bundle=%{_sysconfdir}/pki/tls/certs/ca-bundle.crt"
%global _configure ../configure %global _configure ../configure
@ -304,6 +292,9 @@ install -m 644 docs/libcurl/libcurl.m4 $RPM_BUILD_ROOT%{_datadir}/aclocal
%{_libdir}/libcurl.so.[0-9].[0-9].[0-9].minimal %{_libdir}/libcurl.so.[0-9].[0-9].[0-9].minimal
%changelog %changelog
* Thu Apr 27 2017 Kamil Dudka <kdudka@redhat.com> 7.54.0-3
- switch the TLS backend back to OpenSSL (#1445153)
* Tue Apr 25 2017 Kamil Dudka <kdudka@redhat.com> 7.54.0-2 * Tue Apr 25 2017 Kamil Dudka <kdudka@redhat.com> 7.54.0-2
- nss: use libnssckbi.so as the default source of trust - nss: use libnssckbi.so as the default source of trust
- nss: do not leak PKCS #11 slot while loading a key (#1444860) - nss: do not leak PKCS #11 slot while loading a key (#1444860)