gsskrb5: fix _gssapi_wrap_iov_length_cfx() - there's more than just krb5 overhead...

metze

Signed-off-by: Love Hornquist Astrand <lha@h5l.org>
This commit is contained in:
Stefan Metzmacher
2009-08-17 09:42:32 +02:00
committed by Love Hornquist Astrand
parent 1a0423fd3d
commit f286dd5d64

View File

@@ -937,9 +937,16 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
int iov_count)
{
OM_uint32 major_status;
size_t size;
int i;
size_t *padding = NULL;
gss_iov_buffer_desc *header = NULL;
gss_iov_buffer_desc *padding = NULL;
gss_iov_buffer_desc *trailer = NULL;
size_t gsshsize = 0;
size_t gsstsize = 0;
size_t k5hsize = 0;
size_t k5tsize = 0;
GSSAPI_KRB5_INIT (&context);
*minor_status = 0;
@@ -952,21 +959,25 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
size += iov[i].buffer.length;
break;
case GSS_IOV_BUFFER_TYPE_HEADER:
*minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &iov[i].buffer.length);
if (*minor_status)
if (header != NULL) {
*minor_status = 0;
return GSS_S_FAILURE;
}
header = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_TRAILER:
*minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &iov[i].buffer.length);
if (*minor_status)
if (trailer != NULL) {
*minor_status = 0;
return GSS_S_FAILURE;
}
trailer = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_PADDING:
if (padding != NULL) {
*minor_status = 0;
return GSS_S_FAILURE;
}
padding = &iov[i].buffer.length;
padding = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
break;
@@ -975,15 +986,83 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
}
major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
if (major_status != GSS_S_COMPLETE) {
return major_status;
}
if (conf_req_flag) {
size_t k5psize = 0;
size_t k5pbase = 0;
size_t k5bsize = 0;
size_t ec = 0;
size += sizeof(gss_cfx_wrap_token_desc);
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_HEADER,
&k5hsize);
if (*minor_status)
return GSS_S_FAILURE;
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_TRAILER,
&k5tsize);
if (*minor_status)
return GSS_S_FAILURE;
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_PADDING,
&k5pbase);
if (*minor_status)
return GSS_S_FAILURE;
if (k5pbase > 1) {
k5psize = k5pbase - (size % k5pbase);
} else {
k5psize = 0;
}
if (k5psize == 0 && IS_DCE_STYLE(ctx)) {
*minor_status = krb5_crypto_getblocksize(context, ctx->crypto,
&k5bsize);
if (*minor_status)
return GSS_S_FAILURE;
ec = k5bsize;
} else {
ec = k5psize;
}
gsshsize = sizeof(gss_cfx_wrap_token_desc) + k5hsize;
gsstsize = sizeof(gss_cfx_wrap_token_desc) + ec + k5tsize;
} else {
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_CHECKSUM,
&k5tsize);
if (*minor_status)
return GSS_S_FAILURE;
gsshsize = sizeof(gss_cfx_wrap_token_desc);
gsstsize = k5tsize;
}
if (trailer != NULL) {
trailer->buffer.length = gsstsize;
} else {
gsshsize += gsstsize;
}
header->buffer.length = gsshsize;
if (padding) {
size_t pad;
krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &pad);
if (pad > 1) {
*padding = pad - (size % pad);
if (*padding == pad)
*padding = 0;
} else
*padding = 0;
/* padding is done via EC and is contained in the header or trailer */
padding->buffer.length = 0;
}
if (conf_state) {
*conf_state = conf_req_flag;
}
return GSS_S_COMPLETE;