From 9b261c008a395a323e0516f4cd3f3134aa050577 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Jun 2009 19:06:16 +1000 Subject: s4:heimdal: import lorikeet-heimdal-200906080040 (commit 904d0124b46eed7a8ad6e5b73e892ff34b6865ba) Also including the supporting changes required to pass make test A number of heimdal functions and constants have changed since we last imported a tree (for the better, but inconvenient for us). Andrew Bartlett --- source4/heimdal/lib/gssapi/krb5/aeap.c | 271 +++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 source4/heimdal/lib/gssapi/krb5/aeap.c (limited to 'source4/heimdal/lib/gssapi/krb5/aeap.c') diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c new file mode 100644 index 0000000000..7dab7877d7 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/aeap.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gsskrb5_locl.h" + +#include + +static OM_uint32 +iov_allocate(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count) +{ + unsigned int i; + + for (i = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_FLAGS(iov[i].type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE){ + void *ptr = malloc(iov[i].buffer.length); + if (ptr == NULL) + abort(); + if (iov[i].buffer.value) + memcpy(ptr, iov[i].buffer.value, iov[i].buffer.length); + iov[i].buffer.value = ptr; + iov[i].type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED; + } + } + return GSS_S_COMPLETE; +} + +static OM_uint32 +iov_map(OM_uint32 *minor_status, + const gss_iov_buffer_desc *iov, + int iov_count, + krb5_crypto_iov *data) +{ + unsigned int i; + + for (i = 0; i < iov_count; i++) { + switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_EMPTY: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + case GSS_IOV_BUFFER_TYPE_DATA: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + case GSS_IOV_BUFFER_TYPE_HEADER: + data[i].flags = KRB5_CRYPTO_TYPE_HEADER; + break; + case GSS_IOV_BUFFER_TYPE_TRAILER: + data[i].flags = KRB5_CRYPTO_TYPE_TRAILER; + break; + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_PADDING; + break; + case GSS_IOV_BUFFER_TYPE_STREAM: + abort(); + break; + default: + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + data[i].data.data = iov[i].buffer.value; + data[i].data.length = iov[i].buffer.length; + } + return GSS_S_COMPLETE; +} + +OM_uint32 GSSAPI_LIB_FUNCTION +_gk_wrap_iov(OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + int * conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; + krb5_context context; + OM_uint32 major_status, junk; + krb5_crypto_iov *data; + krb5_error_code ret; + unsigned usage; + + GSSAPI_KRB5_INIT (&context); + + major_status = iov_allocate(minor_status, iov, iov_count); + if (major_status != GSS_S_COMPLETE) + return major_status; + + data = calloc(iov_count, sizeof(data[0])); + if (data == NULL) { + gss_release_iov_buffer(&junk, iov, iov_count); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + major_status = iov_map(minor_status, iov, iov_count, data); + if (major_status != GSS_S_COMPLETE) { + gss_release_iov_buffer(&junk, iov, iov_count); + free(data); + return major_status; + } + + if (ctx->more_flags & LOCAL) { + usage = KRB5_KU_USAGE_ACCEPTOR_SIGN; + } else { + usage = KRB5_KU_USAGE_INITIATOR_SIGN; + } + + ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, + data, iov_count, NULL); + free(data); + if (ret) { + gss_release_iov_buffer(&junk, iov, iov_count); + *minor_status = ret; + return GSS_S_FAILURE; + } + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 GSSAPI_LIB_FUNCTION +_gk_unwrap_iov(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int *conf_state, + gss_qop_t *qop_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; + krb5_context context; + krb5_error_code ret; + OM_uint32 major_status, junk; + krb5_crypto_iov *data; + unsigned usage; + + GSSAPI_KRB5_INIT (&context); + + major_status = iov_allocate(minor_status, iov, iov_count); + if (major_status != GSS_S_COMPLETE) + return major_status; + + data = calloc(iov_count, sizeof(data[0])); + if (data == NULL) { + gss_release_iov_buffer(&junk, iov, iov_count); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + major_status = iov_map(minor_status, iov, iov_count, data); + if (major_status != GSS_S_COMPLETE) { + gss_release_iov_buffer(&junk, iov, iov_count); + free(data); + return major_status; + } + + if (ctx->more_flags & LOCAL) { + usage = KRB5_KU_USAGE_INITIATOR_SIGN; + } else { + usage = KRB5_KU_USAGE_ACCEPTOR_SIGN; + } + + ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, + data, iov_count, NULL); + free(data); + if (ret) { + *minor_status = ret; + gss_release_iov_buffer(&junk, iov, iov_count); + return GSS_S_FAILURE; + } + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 GSSAPI_LIB_FUNCTION +_gk_wrap_iov_length(OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; + krb5_context context; + unsigned int i; + size_t size; + size_t *padding = NULL; + + GSSAPI_KRB5_INIT (&context); + *minor_status = 0; + + for (size = 0, i = 0; i < iov_count; i++) { + switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_EMPTY: + break; + case GSS_IOV_BUFFER_TYPE_DATA: + size += iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_HEADER: + iov[i].buffer.length = + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER); + size += iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_TRAILER: + iov[i].buffer.length = + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER); + size += iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_PADDING: + if (padding != NULL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + padding = &iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_STREAM: + size += iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + break; + default: + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + } + if (padding) { + size_t pad = krb5_crypto_length(context, ctx->crypto, + KRB5_CRYPTO_TYPE_PADDING); + if (pad > 1) { + *padding = pad - (size % pad); + if (*padding == pad) + *padding = 0; + } else + *padding = 0; + } + + return GSS_S_COMPLETE; +} -- cgit