aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Dudka <kdudka@redhat.com>2011-01-04 13:52:54 +0100
committerKamil Dudka <kdudka@redhat.com>2011-01-04 17:20:43 +0100
commitd8f6d1c3341cfc5a1263e1f3f339b64e10b75dc3 (patch)
tree6226d58cddb4ac13045941ffa926d39ee545f512
parent1e52ea92ebcb2c8ba8f9a18005bf54bdb6bc7dd2 (diff)
nss: avoid CURLE_OUT_OF_MEMORY given a file name without any slash
Bug: https://bugzilla.redhat.com/623663
-rw-r--r--RELEASE-NOTES2
-rw-r--r--docs/curl.15
-rw-r--r--docs/libcurl/curl_easy_setopt.35
-rw-r--r--lib/nss.c73
4 files changed, 47 insertions, 38 deletions
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 3fce8e78f..aa67721ab 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -26,7 +26,7 @@ This release includes the following bugfixes:
o Curl_nss_connect: avoid PATH_MAX
o Curl_do: avoid using stale conn pointer
o tftpd test server: avoid buffer overflow report from glibc
- o
+ o nss: avoid CURLE_OUT_OF_MEMORY given a file name without any slash
This release includes the following known bugs:
diff --git a/docs/curl.1 b/docs/curl.1
index e8216d45a..53ae8d787 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -358,11 +358,12 @@ this option assumes a \&"certificate" file that is the private key and the
private certificate concatenated! See \fI--cert\fP and \fI--key\fP to specify
them independently.
-If curl is built against the NSS SSL library then this option tells
+If curl is built against the NSS SSL library then this option can tell
curl the nickname of the certificate to use within the NSS database defined
by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
-loaded.
+loaded. If you want to use a file from the current directory, please precede
+it with "./" prefix, in order to avoid confusion with a nickname.
If this option is used several times, the last one will be used.
.IP "--cert-type <type>"
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index a725b33cb..8c14c7dcc 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -1811,8 +1811,9 @@ Pass a pointer to a zero terminated string as parameter. The string should be
the file name of your certificate. The default format is "PEM" and can be
changed with \fICURLOPT_SSLCERTTYPE\fP.
-With NSS this is the nickname of the certificate you wish to authenticate
-with.
+With NSS this can also be the nickname of the certificate you wish to
+authenticate with. If you want to use a file from the current directory, please
+precede it with "./" prefix, in order to avoid confusion with a nickname.
.IP CURLOPT_SSLCERTTYPE
Pass a pointer to a zero terminated string as parameter. The string should be
the format of your certificate. Supported formats are "PEM" and "DER". (Added
diff --git a/lib/nss.c b/lib/nss.c
index 26bc6e4d9..7db2d8d76 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -277,22 +277,35 @@ static int is_file(const char *filename)
return 0;
}
-static char *fmt_nickname(char *str, bool *nickname_alloc)
+/* Return on heap allocated filename/nickname of a certificate. The returned
+ * string should be later deallocated using free(). *is_nickname is set to TRUE
+ * if the given string is treated as nickname; FALSE if the given string is
+ * treated as file name.
+ */
+static char *fmt_nickname(struct SessionHandle *data, enum dupstring cert_kind,
+ bool *is_nickname)
{
- char *nickname = NULL;
- *nickname_alloc = FALSE;
-
- if(is_file(str)) {
- char *n = strrchr(str, '/');
- if(n) {
- *nickname_alloc = TRUE;
- n++; /* skip last slash */
- nickname = aprintf("PEM Token #%d:%s", 1, n);
- }
- return nickname;
+ const char *str = data->set.str[cert_kind];
+ const char *n;
+ *is_nickname = TRUE;
+
+ if(!is_file(str))
+ /* no such file exists, use the string as nickname */
+ return strdup(str);
+
+ /* search the last slash; we require at least one slash in a file name */
+ n = strrchr(str, '/');
+ if(!n) {
+ infof(data, "warning: certificate file name \"%s\" handled as nickname; "
+ "please use \"./%s\" to force file name\n", str, str);
+ return strdup(str);
}
- return str;
+ /* we'll use the PEM reader to read the certificate from file */
+ *is_nickname = FALSE;
+
+ n++; /* skip last slash */
+ return aprintf("PEM Token #%d:%s", 1, n);
}
static int nss_load_cert(struct ssl_connect_data *ssl,
@@ -1304,25 +1317,20 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
}
if(data->set.str[STRING_CERT]) {
- bool nickname_alloc = FALSE;
- char *nickname = fmt_nickname(data->set.str[STRING_CERT], &nickname_alloc);
+ bool is_nickname;
+ char *nickname = fmt_nickname(data, STRING_CERT, &is_nickname);
if(!nickname)
return CURLE_OUT_OF_MEMORY;
- if(!cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
- data->set.str[STRING_KEY])) {
+ if(!is_nickname && !cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
+ data->set.str[STRING_KEY])) {
/* failf() is already done in cert_stuff() */
- if(nickname_alloc)
- free(nickname);
+ free(nickname);
return CURLE_SSL_CERTPROBLEM;
}
- /* this "takes over" the pointer to the allocated name or makes a
- dup of it */
- connssl->client_nickname = nickname_alloc?nickname:strdup(nickname);
- if(!connssl->client_nickname)
- return CURLE_OUT_OF_MEMORY;
-
+ /* store the nickname for SelectClientCert() called during handshake */
+ connssl->client_nickname = nickname;
}
else
connssl->client_nickname = NULL;
@@ -1376,18 +1384,17 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
display_conn_info(conn, connssl->handle);
if (data->set.str[STRING_SSL_ISSUERCERT]) {
- SECStatus ret;
- bool nickname_alloc = FALSE;
- char *nickname = fmt_nickname(data->set.str[STRING_SSL_ISSUERCERT],
- &nickname_alloc);
-
+ SECStatus ret = SECFailure;
+ bool is_nickname;
+ char *nickname = fmt_nickname(data, STRING_SSL_ISSUERCERT, &is_nickname);
if(!nickname)
return CURLE_OUT_OF_MEMORY;
- ret = check_issuer_cert(connssl->handle, nickname);
+ if(is_nickname)
+ /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
+ ret = check_issuer_cert(connssl->handle, nickname);
- if(nickname_alloc)
- free(nickname);
+ free(nickname);
if(SECFailure == ret) {
infof(data,"SSL certificate issuer check failed\n");