krb5: Implement krb5_verify_checksum_iov with iovecs

Instead of flattening the iovecs passed into
krb5_verify_checksum_iov, create a new internal verify_checksum_iov
function which passes iovecs down onto the individual ->verify or
->checksum functions.
This commit is contained in:
Simon Wilkinson
2018-05-14 14:20:58 +01:00
committed by Jeffrey Altman
parent 152a23f2ce
commit fa1e998b53

View File

@@ -497,18 +497,17 @@ krb5_create_checksum(krb5_context context,
} }
static krb5_error_code static krb5_error_code
verify_checksum(krb5_context context, verify_checksum_iov(krb5_context context,
krb5_crypto crypto, krb5_crypto crypto,
unsigned usage, /* not krb5_key_usage */ unsigned usage, /* not krb5_key_usage */
void *data, struct krb5_crypto_iov *iov,
size_t len, int niov,
Checksum *cksum) Checksum *cksum)
{ {
krb5_error_code ret; krb5_error_code ret;
struct _krb5_key_data *dkey; struct _krb5_key_data *dkey;
Checksum c; Checksum c;
struct _krb5_checksum_type *ct; struct _krb5_checksum_type *ct;
struct krb5_crypto_iov iov[1];
ct = _krb5_find_checksum(cksum->cksumtype); ct = _krb5_find_checksum(cksum->cksumtype);
if (ct == NULL || (ct->flags & F_DISABLED)) { if (ct == NULL || (ct->flags & F_DISABLED)) {
@@ -539,12 +538,8 @@ verify_checksum(krb5_context context,
* calling ->checksum and then compare result. * calling ->checksum and then compare result.
*/ */
iov[0].data.data = data;
iov[0].data.length = len;
iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
if(ct->verify) { if(ct->verify) {
ret = (*ct->verify)(context, dkey, usage, iov, 1, cksum); ret = (*ct->verify)(context, dkey, usage, iov, niov, cksum);
if (ret) if (ret)
krb5_set_error_message(context, ret, krb5_set_error_message(context, ret,
N_("Decrypt integrity check failed for checksum " N_("Decrypt integrity check failed for checksum "
@@ -557,7 +552,7 @@ verify_checksum(krb5_context context,
if (ret) if (ret)
return ret; return ret;
ret = (*ct->checksum)(context, dkey, usage, iov, 1, &c); ret = (*ct->checksum)(context, dkey, usage, iov, niov, &c);
if (ret) { if (ret) {
krb5_data_free(&c.checksum); krb5_data_free(&c.checksum);
return ret; return ret;
@@ -576,6 +571,23 @@ verify_checksum(krb5_context context,
return ret; return ret;
} }
static krb5_error_code
verify_checksum(krb5_context context,
krb5_crypto crypto,
unsigned usage, /* not krb5_key_usage */
void *data,
size_t len,
Checksum *cksum)
{
struct krb5_crypto_iov iov[1];
iov[0].data.data = data;
iov[0].data.length = len;
iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
return verify_checksum_iov(context, crypto, usage, iov, 1, cksum);
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_verify_checksum(krb5_context context, krb5_verify_checksum(krb5_context context,
krb5_crypto crypto, krb5_crypto crypto,
@@ -1940,43 +1952,35 @@ krb5_verify_checksum_iov(krb5_context context,
krb5_cksumtype *type) krb5_cksumtype *type)
{ {
struct _krb5_encryption_type *et = crypto->et; struct _krb5_encryption_type *et = crypto->et;
struct _krb5_checksum_type *ct;
Checksum cksum; Checksum cksum;
krb5_crypto_iov *civ; krb5_crypto_iov *civ;
krb5_error_code ret; krb5_error_code ret;
size_t i; unsigned keyusage;
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;
for (i = 0; i < num_data; i++) {
if (_krb5_crypto_iov_should_sign(&data[i]))
len += data[i].data.length;
}
p = q = malloc(len);
for (i = 0; i < num_data; i++) {
if (_krb5_crypto_iov_should_sign(&data[i])) {
memcpy(q, data[i].data.data, data[i].data.length);
q += data[i].data.length;
}
}
cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum); cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum);
cksum.checksum.length = civ->data.length; cksum.checksum.length = civ->data.length;
cksum.checksum.data = civ->data.data; cksum.checksum.data = civ->data.data;
ret = krb5_verify_checksum(context, crypto, usage, p, len, &cksum); ct = _krb5_find_checksum(cksum.cksumtype);
free(p); if(ct == NULL) {
krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
N_("checksum type %d not supported", ""),
cksum.cksumtype);
return KRB5_PROG_SUMTYPE_NOSUPP;
}
if (arcfour_checksum_p(ct, crypto)) {
keyusage = usage;
_krb5_usage2arcfour(context, &keyusage);
} else
keyusage = CHECKSUM_USAGE(usage);
ret = verify_checksum_iov(context, crypto, keyusage, data, num_data, &cksum);
if (ret == 0 && type) if (ret == 0 && type)
*type = cksum.cksumtype; *type = cksum.cksumtype;