aboutsummaryrefslogtreecommitdiff
path: root/lib
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 /lib
parent1e52ea92ebcb2c8ba8f9a18005bf54bdb6bc7dd2 (diff)
nss: avoid CURLE_OUT_OF_MEMORY given a file name without any slash
Bug: https://bugzilla.redhat.com/623663
Diffstat (limited to 'lib')
-rw-r--r--lib/nss.c73
1 files changed, 40 insertions, 33 deletions
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");