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:
Simon Wilkinson
2018-05-14 14:18:39 +01:00
committed by Jeffrey Altman
parent c2271cfbfb
commit aedc1fd4bd

View File

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