nss: avoid CURLE_OUT_OF_MEMORY given a file name without any slash

Bug: https://bugzilla.redhat.com/623663
This commit is contained in:
Kamil Dudka 2011-01-04 13:52:54 +01:00
parent 1e52ea92eb
commit d8f6d1c334
4 changed files with 46 additions and 37 deletions

View file

@ -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;
const char *str = data->set.str[cert_kind];
const char *n;
*is_nickname = TRUE;
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;
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");