1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

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

@ -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:

View File

@ -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>"

View File

@ -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

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");