diff options
Diffstat (limited to 'src/lib/gssapi/mechglue/g_seal.c')
-rw-r--r-- | src/lib/gssapi/mechglue/g_seal.c | 115 |
1 files changed, 92 insertions, 23 deletions
diff --git a/src/lib/gssapi/mechglue/g_seal.c b/src/lib/gssapi/mechglue/g_seal.c index 95c9b45..9faa5dd 100644 --- a/src/lib/gssapi/mechglue/g_seal.c +++ b/src/lib/gssapi/mechglue/g_seal.c @@ -23,17 +23,17 @@ */ /* - * glue routine for gss_seal + * glue routine for gss_wrap */ #include "mglueP.h" static OM_uint32 -val_seal_args( +val_wrap_args( OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, - int qop_req, + gss_qop_t qop_req, gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer) @@ -66,9 +66,8 @@ val_seal_args( return (GSS_S_COMPLETE); } - OM_uint32 KRB5_CALLCONV -gss_seal (minor_status, +gss_wrap (minor_status, context_handle, conf_req_flag, qop_req, @@ -79,7 +78,7 @@ gss_seal (minor_status, OM_uint32 * minor_status; gss_ctx_id_t context_handle; int conf_req_flag; -int qop_req; +gss_qop_t qop_req; gss_buffer_t input_message_buffer; int * conf_state; gss_buffer_t output_message_buffer; @@ -90,7 +89,7 @@ gss_buffer_t output_message_buffer; gss_union_ctx_id_t ctx; gss_mechanism mech; - status = val_seal_args(minor_status, context_handle, + status = val_wrap_args(minor_status, context_handle, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer); @@ -106,9 +105,8 @@ gss_buffer_t output_message_buffer; mech = gssint_get_mechanism (ctx->mech_type); if (mech) { - if (mech->gss_seal) { - status = mech->gss_seal( - mech->context, + if (mech->gss_wrap) { + status = mech->gss_wrap( minor_status, ctx->internal_ctx_id, conf_req_flag, @@ -118,9 +116,20 @@ gss_buffer_t output_message_buffer; output_message_buffer); if (status != GSS_S_COMPLETE) map_error(minor_status, mech); + } else if (mech->gss_wrap_aead || + (mech->gss_wrap_iov && mech->gss_wrap_iov_length)) { + status = gssint_wrap_aead(mech, + minor_status, + ctx, + conf_req_flag, + (gss_qop_t)qop_req, + GSS_C_NO_BUFFER, + input_message_buffer, + conf_state, + output_message_buffer); } else status = GSS_S_UNAVAILABLE; - + return(status); } /* EXPORT DELETE END */ @@ -129,7 +138,7 @@ gss_buffer_t output_message_buffer; } OM_uint32 KRB5_CALLCONV -gss_wrap (minor_status, +gss_seal (minor_status, context_handle, conf_req_flag, qop_req, @@ -140,19 +149,74 @@ gss_wrap (minor_status, OM_uint32 * minor_status; gss_ctx_id_t context_handle; int conf_req_flag; -gss_qop_t qop_req; +int qop_req; gss_buffer_t input_message_buffer; int * conf_state; gss_buffer_t output_message_buffer; { - return gss_seal(minor_status, (gss_ctx_id_t)context_handle, - conf_req_flag, (int) qop_req, - (gss_buffer_t)input_message_buffer, conf_state, + return gss_wrap(minor_status, context_handle, + conf_req_flag, (gss_qop_t) qop_req, + input_message_buffer, conf_state, output_message_buffer); } /* + * It is only possible to implement gss_wrap_size_limit() on top + * of gss_wrap_iov_length() for mechanisms that do not use any + * padding and have fixed length headers/trailers. + */ +static OM_uint32 +gssint_wrap_size_limit_iov_shim(gss_mechanism mech, + OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 req_output_size, + OM_uint32 *max_input_size) +{ + gss_iov_buffer_desc iov[4]; + OM_uint32 status; + OM_uint32 ohlen; + + iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; + iov[0].buffer.value = NULL; + iov[0].buffer.length = 0; + + iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; + iov[1].buffer.length = req_output_size; + iov[1].buffer.value = NULL; + + iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING; + iov[2].buffer.value = NULL; + iov[2].buffer.length = 0; + + iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER; + iov[3].buffer.value = NULL; + iov[3].buffer.length = 0; + + assert(mech->gss_wrap_iov_length); + + status = mech->gss_wrap_iov_length(minor_status, context_handle, + conf_req_flag, qop_req, + NULL, iov, + sizeof(iov)/sizeof(iov[0])); + if (status != GSS_S_COMPLETE) { + map_error(minor_status, mech); + return status; + } + + ohlen = iov[0].buffer.length + iov[3].buffer.length; + + if (iov[2].buffer.length == 0 && ohlen < req_output_size) + *max_input_size = req_output_size - ohlen; + else + *max_input_size = 0; + + return GSS_S_COMPLETE; +} + +/* * New for V2 */ OM_uint32 KRB5_CALLCONV @@ -190,13 +254,18 @@ gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, if (!mech) return (GSS_S_BAD_MECH); - if (!mech->gss_wrap_size_limit) - return (GSS_S_UNAVAILABLE); - - major_status = mech->gss_wrap_size_limit(mech->context, minor_status, - ctx->internal_ctx_id, - conf_req_flag, qop_req, - req_output_size, max_input_size); + if (mech->gss_wrap_size_limit) + major_status = mech->gss_wrap_size_limit(minor_status, + ctx->internal_ctx_id, + conf_req_flag, qop_req, + req_output_size, max_input_size); + else if (mech->gss_wrap_iov_length) + major_status = gssint_wrap_size_limit_iov_shim(mech, minor_status, + ctx->internal_ctx_id, + conf_req_flag, qop_req, + req_output_size, max_input_size); + else + major_status = GSS_S_UNAVAILABLE; if (major_status != GSS_S_COMPLETE) map_error(minor_status, mech); return major_status; |