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