krb5: Use iovecs throughout krb5_create_checksum_iov
Rather than flattening the iovecs supplied to krb5_create_checksum_iov into a malloc()'d memory block, refactor the function so that they can be passed straight through to the backend hash functions.
This commit is contained in:

committed by
Jeffrey Altman

parent
c2271cfbfb
commit
aedc1fd4bd
@@ -398,17 +398,16 @@ get_checksum_key(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
create_checksum (krb5_context context,
|
create_checksum_iov(krb5_context context,
|
||||||
struct _krb5_checksum_type *ct,
|
struct _krb5_checksum_type *ct,
|
||||||
krb5_crypto crypto,
|
krb5_crypto crypto,
|
||||||
unsigned usage,
|
unsigned usage,
|
||||||
void *data,
|
struct krb5_crypto_iov *iov,
|
||||||
size_t len,
|
int niov,
|
||||||
Checksum *result)
|
Checksum *result)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
struct _krb5_key_data *dkey;
|
struct _krb5_key_data *dkey;
|
||||||
struct krb5_crypto_iov iov[1];
|
|
||||||
|
|
||||||
if (ct->flags & F_DISABLED) {
|
if (ct->flags & F_DISABLED) {
|
||||||
krb5_clear_error_message (context);
|
krb5_clear_error_message (context);
|
||||||
@@ -420,15 +419,33 @@ create_checksum (krb5_context context,
|
|||||||
return ret;
|
return ret;
|
||||||
} else
|
} else
|
||||||
dkey = NULL;
|
dkey = NULL;
|
||||||
|
|
||||||
result->cksumtype = ct->type;
|
result->cksumtype = ct->type;
|
||||||
|
|
||||||
|
return (*ct->checksum)(context, dkey, usage, iov, niov, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
create_checksum (krb5_context context,
|
||||||
|
struct _krb5_checksum_type *ct,
|
||||||
|
krb5_crypto crypto,
|
||||||
|
unsigned usage,
|
||||||
|
void *data,
|
||||||
|
size_t len,
|
||||||
|
Checksum *result)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct krb5_crypto_iov iov[1];
|
||||||
|
|
||||||
ret = krb5_data_alloc(&result->checksum, ct->checksumsize);
|
ret = krb5_data_alloc(&result->checksum, ct->checksumsize);
|
||||||
if (ret)
|
if (ret)
|
||||||
return (ret);
|
return ret;
|
||||||
|
|
||||||
iov[0].data.data = data;
|
iov[0].data.data = data;
|
||||||
iov[0].data.length = len;
|
iov[0].data.length = len;
|
||||||
iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||||
return (*ct->checksum)(context, dkey, usage, iov, 1, result);
|
|
||||||
|
return create_checksum_iov(context, ct, crypto, usage, iov, 1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1857,53 +1874,42 @@ krb5_create_checksum_iov(krb5_context context,
|
|||||||
{
|
{
|
||||||
Checksum cksum;
|
Checksum cksum;
|
||||||
krb5_crypto_iov *civ;
|
krb5_crypto_iov *civ;
|
||||||
|
struct _krb5_checksum_type *ct;
|
||||||
|
unsigned keyusage;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
size_t i;
|
|
||||||
size_t len;
|
|
||||||
char *p, *q;
|
|
||||||
|
|
||||||
if(!derived_crypto(context, crypto)) {
|
|
||||||
krb5_clear_error_message(context);
|
|
||||||
return KRB5_CRYPTO_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
civ = iov_find(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM);
|
civ = iov_find(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM);
|
||||||
if (civ == NULL)
|
if (civ == NULL)
|
||||||
return KRB5_BAD_MSIZE;
|
return KRB5_BAD_MSIZE;
|
||||||
|
|
||||||
len = 0;
|
ct = crypto->et->keyed_checksum;
|
||||||
for (i = 0; i < num_data; i++) {
|
if (ct == NULL)
|
||||||
if (_krb5_crypto_iov_should_sign(&data[i]))
|
ct = crypto->et->checksum;
|
||||||
len += data[i].data.length;
|
|
||||||
|
if(ct == NULL) {
|
||||||
|
krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
|
||||||
|
N_("checksum type not found", ""));
|
||||||
|
return KRB5_PROG_SUMTYPE_NOSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = q = malloc(len);
|
if (arcfour_checksum_p(ct, crypto)) {
|
||||||
|
keyusage = usage;
|
||||||
|
_krb5_usage2arcfour(context, &keyusage);
|
||||||
|
} else
|
||||||
|
keyusage = CHECKSUM_USAGE(usage);
|
||||||
|
|
||||||
for (i = 0; i < num_data; i++) {
|
if (ct->checksumsize > civ->data.length) {
|
||||||
if (_krb5_crypto_iov_should_sign(&data[i])) {
|
|
||||||
memcpy(q, data[i].data.data, data[i].data.length);
|
|
||||||
q += data[i].data.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = krb5_create_checksum(context, crypto, usage, 0, p, len, &cksum);
|
|
||||||
free(p);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (type)
|
|
||||||
*type = cksum.cksumtype;
|
|
||||||
|
|
||||||
if (cksum.checksum.length > civ->data.length) {
|
|
||||||
krb5_set_error_message(context, KRB5_BAD_MSIZE,
|
krb5_set_error_message(context, KRB5_BAD_MSIZE,
|
||||||
N_("Checksum larger then input buffer", ""));
|
N_("Checksum larger then input buffer", ""));
|
||||||
free_Checksum(&cksum);
|
|
||||||
return KRB5_BAD_MSIZE;
|
return KRB5_BAD_MSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
civ->data.length = cksum.checksum.length;
|
cksum.checksum = civ->data;
|
||||||
memcpy(civ->data.data, cksum.checksum.data, civ->data.length);
|
ret = create_checksum_iov(context, ct, crypto, keyusage,
|
||||||
free_Checksum(&cksum);
|
data, num_data, &cksum);
|
||||||
|
|
||||||
|
if (type)
|
||||||
|
*type = cksum.cksumtype;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user