From f286dd5d64d9b6cca7e0cd7bdf8af038bfe4bd3d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 17 Aug 2009 09:42:32 +0200 Subject: [PATCH] gsskrb5: fix _gssapi_wrap_iov_length_cfx() - there's more than just krb5 overhead... metze Signed-off-by: Love Hornquist Astrand --- lib/gssapi/krb5/cfx.c | 107 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 14 deletions(-) diff --git a/lib/gssapi/krb5/cfx.c b/lib/gssapi/krb5/cfx.c index 179e25ab1..ac1760408 100755 --- a/lib/gssapi/krb5/cfx.c +++ b/lib/gssapi/krb5/cfx.c @@ -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;