mirror of
https://github.com/moparisthebest/curl
synced 2025-02-28 17:31:46 -05:00
nss: fix a bug in handling of CURLOPT_CAPATH
... and update the curl.1 and curl_easy_setopt.3 man pages such that they do not suggest to use an OpenSSL utility if curl is not built against OpenSSL. Bug: https://bugzilla.redhat.com/669702
This commit is contained in:
parent
ef46fcdd90
commit
fc77790bcd
@ -27,6 +27,7 @@ This release includes the following bugfixes:
|
|||||||
o Curl_do: avoid using stale conn pointer
|
o Curl_do: avoid using stale conn pointer
|
||||||
o tftpd test server: avoid buffer overflow report from glibc
|
o tftpd test server: avoid buffer overflow report from glibc
|
||||||
o nss: avoid CURLE_OUT_OF_MEMORY given a file name without any slash
|
o nss: avoid CURLE_OUT_OF_MEMORY given a file name without any slash
|
||||||
|
o nss: fix a bug in handling of CURLOPT_CAPATH
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
|
10
docs/curl.1
10
docs/curl.1
@ -394,11 +394,11 @@ may be loaded.
|
|||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--capath <CA certificate directory>"
|
.IP "--capath <CA certificate directory>"
|
||||||
(SSL) Tells curl to use the specified certificate directory to verify the
|
(SSL) Tells curl to use the specified certificate directory to verify the
|
||||||
peer. The certificates must be in PEM format, and the directory must have been
|
peer. The certificates must be in PEM format, and if curl is built against
|
||||||
processed using the c_rehash utility supplied with openssl. Using
|
OpenSSL, the directory must have been processed using the c_rehash utility
|
||||||
\fI--capath\fP can allow curl to make SSL-connections much more efficiently
|
supplied with OpenSSL. Using \fI--capath\fP can allow OpenSSL-powered curl to
|
||||||
than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA
|
make SSL-connections much more efficiently than using \fI--cacert\fP if the
|
||||||
certificates.
|
\fI--cacert\fP file contains many CA certificates.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-f/--fail"
|
.IP "-f/--fail"
|
||||||
|
@ -1924,13 +1924,15 @@ mismatch with the issuer of peer certificate (\fICURLOPT_SSL_VERIFYPEER\fP has
|
|||||||
to be set too for the check to fail). (Added in 7.19.0)
|
to be set too for the check to fail). (Added in 7.19.0)
|
||||||
.IP CURLOPT_CAPATH
|
.IP CURLOPT_CAPATH
|
||||||
Pass a char * to a zero terminated string naming a directory holding multiple
|
Pass a char * to a zero terminated string naming a directory holding multiple
|
||||||
CA certificates to verify the peer with. The certificate directory must be
|
CA certificates to verify the peer with. If libcurl is built against OpenSSL,
|
||||||
prepared using the openssl c_rehash utility. This makes sense only when used
|
the certificate directory must be prepared using the openssl c_rehash utility.
|
||||||
in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
This makes sense only when used in combination with the
|
||||||
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAPATH\fP need not even
|
\fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP is zero,
|
||||||
indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently
|
\fICURLOPT_CAPATH\fP need not even indicate an accessible path. The
|
||||||
does not work in Windows due to some limitation in openssl. This option is
|
\fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some
|
||||||
OpenSSL-specific and does nothing if libcurl is built to use GnuTLS.
|
limitation in openssl. This option is OpenSSL-specific and does nothing if
|
||||||
|
libcurl is built to use GnuTLS. NSS-powered libcurl provides the option only
|
||||||
|
for backward compatibility.
|
||||||
.IP CURLOPT_CRLFILE
|
.IP CURLOPT_CRLFILE
|
||||||
Pass a char * to a zero terminated string naming a file with the concatenation
|
Pass a char * to a zero terminated string naming a file with the concatenation
|
||||||
of CRL (in PEM format) to use in the certificate validation that occurs during
|
of CRL (in PEM format) to use in the certificate validation that occurs during
|
||||||
|
106
lib/nss.c
106
lib/nss.c
@ -1108,6 +1108,55 @@ static bool handle_cc_error(PRInt32 err, struct SessionHandle *data)
|
|||||||
static Curl_recv nss_recv;
|
static Curl_recv nss_recv;
|
||||||
static Curl_send nss_send;
|
static Curl_send nss_send;
|
||||||
|
|
||||||
|
static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
||||||
|
int sockindex)
|
||||||
|
{
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
const char *cafile = data->set.ssl.CAfile;
|
||||||
|
const char *capath = data->set.ssl.CApath;
|
||||||
|
|
||||||
|
if(cafile && !nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE))
|
||||||
|
return CURLE_SSL_CACERT_BADFILE;
|
||||||
|
|
||||||
|
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, 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(!nss_load_cert(&conn->ssl[sockindex], 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\n", fullpath);
|
||||||
|
|
||||||
|
free(fullpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
PR_CloseDir(dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
PRInt32 err;
|
PRInt32 err;
|
||||||
@ -1249,62 +1298,9 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
NULL) != SECSuccess)
|
NULL) != SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if(!data->set.ssl.verifypeer)
|
if(data->set.ssl.verifypeer && (CURLE_OK !=
|
||||||
/* skip the verifying of the peer */
|
(curlerr = nss_load_ca_certificates(conn, sockindex))))
|
||||||
;
|
|
||||||
else if(data->set.ssl.CAfile) {
|
|
||||||
int rc = nss_load_cert(&conn->ssl[sockindex], data->set.ssl.CAfile,
|
|
||||||
PR_TRUE);
|
|
||||||
if(!rc) {
|
|
||||||
curlerr = CURLE_SSL_CACERT_BADFILE;
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(data->set.ssl.CApath) {
|
|
||||||
struct_stat st;
|
|
||||||
PRDir *dir;
|
|
||||||
PRDirEntry *entry;
|
|
||||||
|
|
||||||
if(stat(data->set.ssl.CApath, &st) == -1) {
|
|
||||||
curlerr = CURLE_SSL_CACERT_BADFILE;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(S_ISDIR(st.st_mode)) {
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
dir = PR_OpenDir(data->set.ssl.CApath);
|
|
||||||
do {
|
|
||||||
entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN);
|
|
||||||
|
|
||||||
if(entry) {
|
|
||||||
char *fullpath;
|
|
||||||
size_t pathlen = strlen(data->set.ssl.CApath) +
|
|
||||||
strlen(entry->name) + 2; /* add two, for slash and trailing zero */
|
|
||||||
fullpath = malloc(pathlen);
|
|
||||||
if(!fullpath) {
|
|
||||||
PR_CloseDir(dir);
|
|
||||||
curlerr = CURLE_OUT_OF_MEMORY;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(fullpath, pathlen, "%s/%s", data->set.ssl.CApath,
|
|
||||||
entry->name);
|
|
||||||
rc = nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE);
|
|
||||||
/* FIXME: check this return value! */
|
|
||||||
free(fullpath);
|
|
||||||
}
|
|
||||||
/* This is purposefully tolerant of errors so non-PEM files
|
|
||||||
* can be in the same directory */
|
|
||||||
} while(entry != NULL);
|
|
||||||
PR_CloseDir(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
infof(data,
|
|
||||||
" CAfile: %s\n"
|
|
||||||
" CApath: %s\n",
|
|
||||||
data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
|
|
||||||
data->set.ssl.CApath ? data->set.ssl.CApath : "none");
|
|
||||||
|
|
||||||
if (data->set.ssl.CRLfile) {
|
if (data->set.ssl.CRLfile) {
|
||||||
if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) {
|
if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user