Loading RELEASE-NOTES +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ This release includes the following bugfixes: o Curl_do: avoid using stale conn pointer 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: fix a bug in handling of CURLOPT_CAPATH This release includes the following known bugs: Loading docs/curl.1 +5 −5 Original line number Diff line number Diff line Loading @@ -394,11 +394,11 @@ may be loaded. If this option is used several times, the last one will be used. .IP "--capath <CA certificate directory>" (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 processed using the c_rehash utility supplied with openssl. Using \fI--capath\fP can allow curl to make SSL-connections much more efficiently than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA certificates. peer. The certificates must be in PEM format, and if curl is built against OpenSSL, the directory must have been processed using the c_rehash utility supplied with OpenSSL. Using \fI--capath\fP can allow OpenSSL-powered curl to make SSL-connections much more efficiently than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA certificates. If this option is used several times, the last one will be used. .IP "-f/--fail" Loading docs/libcurl/curl_easy_setopt.3 +9 −7 Original line number Diff line number Diff line Loading @@ -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) .IP CURLOPT_CAPATH 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 prepared using the openssl c_rehash utility. This makes sense only when used in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAPATH\fP need not even indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some limitation in openssl. This option is OpenSSL-specific and does nothing if libcurl is built to use GnuTLS. CA certificates to verify the peer with. If libcurl is built against OpenSSL, the certificate directory must be prepared using the openssl c_rehash utility. This makes sense only when used in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAPATH\fP need not even indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some 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 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 Loading lib/nss.c +52 −56 Original line number Diff line number Diff line Loading @@ -1108,6 +1108,55 @@ static bool handle_cc_error(PRInt32 err, struct SessionHandle *data) static Curl_recv nss_recv; 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) { PRInt32 err; Loading Loading @@ -1249,62 +1298,9 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) NULL) != SECSuccess) goto error; if(!data->set.ssl.verifypeer) /* skip the verifying of the peer */ ; 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; } } 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; if(data->set.ssl.verifypeer && (CURLE_OK != (curlerr = nss_load_ca_certificates(conn, sockindex)))) 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(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) { Loading Loading
RELEASE-NOTES +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ This release includes the following bugfixes: o Curl_do: avoid using stale conn pointer 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: fix a bug in handling of CURLOPT_CAPATH This release includes the following known bugs: Loading
docs/curl.1 +5 −5 Original line number Diff line number Diff line Loading @@ -394,11 +394,11 @@ may be loaded. If this option is used several times, the last one will be used. .IP "--capath <CA certificate directory>" (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 processed using the c_rehash utility supplied with openssl. Using \fI--capath\fP can allow curl to make SSL-connections much more efficiently than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA certificates. peer. The certificates must be in PEM format, and if curl is built against OpenSSL, the directory must have been processed using the c_rehash utility supplied with OpenSSL. Using \fI--capath\fP can allow OpenSSL-powered curl to make SSL-connections much more efficiently than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA certificates. If this option is used several times, the last one will be used. .IP "-f/--fail" Loading
docs/libcurl/curl_easy_setopt.3 +9 −7 Original line number Diff line number Diff line Loading @@ -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) .IP CURLOPT_CAPATH 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 prepared using the openssl c_rehash utility. This makes sense only when used in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAPATH\fP need not even indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some limitation in openssl. This option is OpenSSL-specific and does nothing if libcurl is built to use GnuTLS. CA certificates to verify the peer with. If libcurl is built against OpenSSL, the certificate directory must be prepared using the openssl c_rehash utility. This makes sense only when used in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAPATH\fP need not even indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some 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 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 Loading
lib/nss.c +52 −56 Original line number Diff line number Diff line Loading @@ -1108,6 +1108,55 @@ static bool handle_cc_error(PRInt32 err, struct SessionHandle *data) static Curl_recv nss_recv; 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) { PRInt32 err; Loading Loading @@ -1249,62 +1298,9 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) NULL) != SECSuccess) goto error; if(!data->set.ssl.verifypeer) /* skip the verifying of the peer */ ; 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; } } 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; if(data->set.ssl.verifypeer && (CURLE_OK != (curlerr = nss_load_ca_certificates(conn, sockindex)))) 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(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) { Loading