summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2002-04-03 14:54:53 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2002-04-03 14:54:53 +0000
commitfa9b1eab54eb4178e4ca5efe48d723d48a2dad87 (patch)
treed81d6a42a27bdadc461f9121aaee456eb9023c14
parent6b0d0877d9bf0cbafb74ea59401196fb5a48d23c (diff)
downloadgnutls-fa9b1eab54eb4178e4ca5efe48d723d48a2dad87.tar.gz
In gnutls_find_acceptable_client_cert() corrected bug in callback
parameters, and used alloca for issuers_dn allocation.
-rw-r--r--lib/auth_cert.c73
1 files changed, 45 insertions, 28 deletions
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index 5841839cd9..c349afa9dc 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -289,7 +289,6 @@ static int _gnutls_find_acceptable_client_cert(GNUTLS_STATE state,
return GNUTLS_E_INSUFICIENT_CRED;
}
-
if (state->gnutls_internals.client_cert_callback != NULL) {
/* if try>=0 then the client wants automatic
* choose of certificate, otherwise (-1), he
@@ -332,6 +331,35 @@ static int _gnutls_find_acceptable_client_cert(GNUTLS_STATE state,
gnutls_datum *my_certs = NULL;
gnutls_datum *issuers_dn = NULL;
int count;
+ int issuers_dn_len = 0;
+ opaque* dataptr = data;
+ int dataptr_size = data_size;
+
+ /* Count the number of the given issuers;
+ * This is used to allocate the issuers_dn without
+ * using realloc().
+ */
+ do {
+ dataptr_size -= 2;
+ if (dataptr_size <= 0)
+ goto clear;
+ size = READuint16(data);
+
+ dataptr_size -= size;
+ if (dataptr_size < 0)
+ goto clear;
+
+ dataptr += 2;
+
+ issuers_dn_len++;
+
+ dataptr += size;
+
+ if (dataptr_size == 0)
+ break;
+
+ } while (1);
+
my_certs =
gnutls_alloca(cred->ncerts * sizeof(gnutls_datum));
@@ -344,41 +372,29 @@ static int _gnutls_find_acceptable_client_cert(GNUTLS_STATE state,
if (gnutls_cert_type_get(state) == GNUTLS_CRT_X509) {
data = _data;
data_size = _data_size;
- count = 0; /* holds the number of given CA's DN */
- do {
- data_size -= 2;
- if (data_size <= 0)
- goto clear;
- size = READuint16(data);
- data_size -= size;
- if (data_size < 0)
- goto clear;
+ issuers_dn = gnutls_alloca( issuers_dn_len * sizeof(gnutls_datum));
- data += 2;
+ for (i=0;i<issuers_dn_len;i++) {
+ /* The checks here for the buffer boundaries
+ * are not needed since the buffer has been
+ * parsed above.
+ */
+ data_size -= 2;
- issuers_dn =
- gnutls_realloc_fast(issuers_dn,
- (count +
- 1) *
- sizeof
- (gnutls_datum));
- if (issuers_dn == NULL)
- goto clear;
+ size = READuint16(data);
- issuers_dn->data = data;
- issuers_dn->size = size;
+ data += 2;
- count++; /* otherwise we have failed */
+ issuers_dn[count].data = data;
+ issuers_dn[count].size = size;
data += size;
- if (data_size == 0)
- break;
+ }
- } while (1);
} else { /* Other certificate types */
- count = 0;
+ issuers_dn_len = 0;
issuers_dn = NULL;
}
@@ -407,12 +423,13 @@ static int _gnutls_find_acceptable_client_cert(GNUTLS_STATE state,
my_certs[j++] = cred->cert_list[i][0].raw;
}
}
+
indx =
state->gnutls_internals.client_cert_callback(state,
my_certs,
j,
issuers_dn,
- count);
+ issuers_dn_len);
/* the indx returned by the user is relative
* to the certificates we provided him.
@@ -424,7 +441,7 @@ static int _gnutls_find_acceptable_client_cert(GNUTLS_STATE state,
clear:
gnutls_afree(my_certs);
gnutls_afree(ij_map);
- gnutls_free(issuers_dn);
+ gnutls_afree(issuers_dn);
}
*ind = indx;