diff --git a/0002-curl-7.54.0-libnssckbi.patch b/0002-curl-7.54.0-libnssckbi.patch new file mode 100644 index 0000000..df208c8 --- /dev/null +++ b/0002-curl-7.54.0-libnssckbi.patch @@ -0,0 +1,285 @@ +From 50582c5be1a613ee1d212855a8945b4c8ef8950f Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 + diff --git a/curl.spec b/curl.spec index cd3b5c7..f55092b 100644 --- a/curl.spec +++ b/curl.spec @@ -9,6 +9,9 @@ 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 Patch101: 0101-curl-7.32.0-multilib.patch @@ -142,6 +145,7 @@ be installed. # upstream patches %patch1 -p1 +%patch2 -p1 # Fedora patches %patch101 -p1 @@ -173,10 +177,9 @@ export common_configure_opts=" \ --enable-symbol-hiding \ --enable-ipv6 \ --enable-threaded-resolver \ - --with-ca-bundle=%{_sysconfdir}/pki/tls/certs/ca-bundle.crt \ --with-gssapi \ --with-nghttp2 \ - --without-ssl --with-nss" + --without-ssl --with-nss --without-ca-bundle" %global _configure ../configure @@ -302,6 +305,7 @@ install -m 644 docs/libcurl/libcurl.m4 $RPM_BUILD_ROOT%{_datadir}/aclocal %changelog * Tue Apr 25 2017 Kamil Dudka 7.54.0-2 +- nss: use libnssckbi.so as the default source of trust - nss: do not leak PKCS #11 slot while loading a key (#1444860) * Thu Apr 20 2017 Kamil Dudka 7.54.0-1