gss_wrap/gss_unwrap_aead implementation
Signed-off-by: Nicolas Williams <nico@twosigma.com>
This commit is contained in:

committed by
Nicolas Williams

parent
6b5933337b
commit
33ce593b6d
@@ -214,3 +214,121 @@ gss_context_query_attributes(OM_uint32 *minor_status,
|
||||
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* AEAD wrap API for a single piece of associated data, for compatibility
|
||||
* with MIT and as specified by draft-howard-gssapi-aead-00.txt.
|
||||
*
|
||||
* @ingroup gssapi
|
||||
*/
|
||||
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
|
||||
gss_wrap_aead(OM_uint32 *minor_status,
|
||||
gss_ctx_id_t context_handle,
|
||||
int conf_req_flag,
|
||||
gss_qop_t qop_req,
|
||||
gss_buffer_t input_assoc_buffer,
|
||||
gss_buffer_t input_payload_buffer,
|
||||
int *conf_state,
|
||||
gss_buffer_t output_message_buffer)
|
||||
{
|
||||
OM_uint32 major_status, tmp, flags = 0;
|
||||
gss_iov_buffer_desc iov[5];
|
||||
size_t i;
|
||||
unsigned char *p;
|
||||
|
||||
memset(iov, 0, sizeof(iov));
|
||||
|
||||
iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
|
||||
|
||||
iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
|
||||
if (input_assoc_buffer)
|
||||
iov[1].buffer = *input_assoc_buffer;
|
||||
|
||||
iov[2].type = GSS_IOV_BUFFER_TYPE_DATA;
|
||||
if (input_payload_buffer)
|
||||
iov[2].buffer.length = input_payload_buffer->length;
|
||||
|
||||
gss_inquire_context(minor_status, context_handle, NULL, NULL,
|
||||
NULL, NULL, &flags, NULL, NULL);
|
||||
|
||||
/* krb5 mech rejects padding/trailer if DCE-style is set */
|
||||
iov[3].type = (flags & GSS_C_DCE_STYLE) ? GSS_IOV_BUFFER_TYPE_EMPTY
|
||||
: GSS_IOV_BUFFER_TYPE_PADDING;
|
||||
iov[4].type = (flags & GSS_C_DCE_STYLE) ? GSS_IOV_BUFFER_TYPE_EMPTY
|
||||
: GSS_IOV_BUFFER_TYPE_TRAILER;
|
||||
|
||||
major_status = gss_wrap_iov_length(minor_status, context_handle,
|
||||
conf_req_flag, qop_req, conf_state,
|
||||
iov, 5);
|
||||
if (GSS_ERROR(major_status))
|
||||
return major_status;
|
||||
|
||||
for (i = 0, output_message_buffer->length = 0; i < 5; i++) {
|
||||
if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY)
|
||||
continue;
|
||||
|
||||
output_message_buffer->length += iov[i].buffer.length;
|
||||
}
|
||||
|
||||
output_message_buffer->value = malloc(output_message_buffer->length);
|
||||
if (output_message_buffer->value == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0, p = output_message_buffer->value; i < 5; i++) {
|
||||
if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY)
|
||||
continue;
|
||||
else if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA)
|
||||
memcpy(p, input_payload_buffer->value, input_payload_buffer->length);
|
||||
|
||||
iov[i].buffer.value = p;
|
||||
p += iov[i].buffer.length;
|
||||
}
|
||||
|
||||
major_status = gss_wrap_iov(minor_status, context_handle, conf_req_flag,
|
||||
qop_req, conf_state, iov, 5);
|
||||
if (GSS_ERROR(major_status))
|
||||
gss_release_buffer(&tmp, output_message_buffer);
|
||||
|
||||
return major_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* AEAD unwrap for a single piece of associated data, for compatibility
|
||||
* with MIT and as specified by draft-howard-gssapi-aead-00.txt.
|
||||
*
|
||||
* @ingroup gssapi
|
||||
*/
|
||||
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
|
||||
gss_unwrap_aead(OM_uint32 *minor_status,
|
||||
gss_ctx_id_t context_handle,
|
||||
gss_buffer_t input_message_buffer,
|
||||
gss_buffer_t input_assoc_buffer,
|
||||
gss_buffer_t output_payload_buffer,
|
||||
int *conf_state,
|
||||
gss_qop_t *qop_state)
|
||||
{
|
||||
OM_uint32 major_status, tmp;
|
||||
gss_iov_buffer_desc iov[3];
|
||||
|
||||
memset(iov, 0, sizeof(iov));
|
||||
|
||||
iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
|
||||
iov[0].buffer = *input_message_buffer;
|
||||
|
||||
iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
|
||||
if (input_assoc_buffer)
|
||||
iov[1].buffer = *input_assoc_buffer;
|
||||
|
||||
iov[2].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;
|
||||
|
||||
major_status = gss_unwrap_iov(minor_status, context_handle, conf_state,
|
||||
qop_state, iov, 3);
|
||||
if (GSS_ERROR(major_status))
|
||||
gss_release_iov_buffer(&tmp, &iov[2], 1);
|
||||
else
|
||||
*output_payload_buffer = iov[2].buffer;
|
||||
|
||||
return major_status;
|
||||
}
|
||||
|
Reference in New Issue
Block a user