s4:heimdal_build: add aeap files to the build
authorStefan Metzmacher <metze@samba.org>
Wed, 25 Mar 2009 11:23:23 +0000 (12:23 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 26 Mar 2009 19:26:57 +0000 (20:26 +0100)
metze

source4/heimdal/lib/gssapi/krb5/aeap.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_aeap.c [new file with mode: 0644]
source4/heimdal_build/internal.mk

diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c
new file mode 100644 (file)
index 0000000..7dab787
--- /dev/null
@@ -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 <roken.h>
+
+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;
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c
new file mode 100644 (file)
index 0000000..cbe0cd1
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * AEAD support
+ */ 
+
+#include "mech_locl.h"
+RCSID("$Id$");
+
+/**
+ * Encrypts or sign the data.
+ *
+ * The maximum packet size is gss_context_stream_sizes.max_msg_size.
+ *
+ * The caller needs provide the folloing buffers:
+ *
+ * - HEADER (of size gss_context_stream_sizes.header)
+ *   SIGN_ONLY (optional, zero or more)
+ *   DATA
+ *   SIGN_ONLY (optional, zero or more)
+ *   PADDING (of size gss_context_stream_sizes.blocksize)
+ *   TRAILER (of size gss_context_stream_sizes.trailer)
+ *
+ * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the
+ *   DATA elements is padded to a block bountry.
+ *
+ * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER
+ *
+ * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or
+ * gss_context_query_attributes().
+ *
+ * @ingroup gssapi
+ */
+
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_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)
+{
+       struct _gss_context *ctx = (struct _gss_context *) context_handle;
+       gssapi_mech_interface m;
+
+       if (minor_status)
+           *minor_status = 0;
+       if (conf_state)
+           *conf_state = 0;
+       if (ctx == NULL)
+           return GSS_S_NO_CONTEXT;
+       if (iov == NULL && iov_count != 0)
+           return GSS_S_CALL_INACCESSIBLE_READ;
+
+       m = ctx->gc_mech;
+
+       if (m->gm_wrap_iov == NULL) {
+           if (minor_status)
+               *minor_status = 0;
+           return GSS_S_UNAVAILABLE;
+       }
+
+       return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx,
+                               conf_req_flag, qop_req, conf_state,
+                               iov, iov_count);
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_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)
+{
+       struct _gss_context *ctx = (struct _gss_context *) context_handle;
+       gssapi_mech_interface m;          
+
+       if (minor_status)
+           *minor_status = 0;
+       if (conf_state)
+           *conf_state = 0;
+       if (qop_state)
+           *qop_state = 0;
+       if (ctx == NULL)
+           return GSS_S_NO_CONTEXT;
+       if (iov == NULL && iov_count != 0)
+           return GSS_S_CALL_INACCESSIBLE_READ;
+
+       m = ctx->gc_mech;
+
+       if (m->gm_unwrap_iov == NULL) {
+           *minor_status = 0;
+           return GSS_S_UNAVAILABLE;
+       }
+
+       return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx,
+                                 conf_state, qop_state,
+                                 iov, iov_count);
+}
+
+OM_uint32  GSSAPI_LIB_FUNCTION
+gss_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)
+{
+       struct _gss_context *ctx = (struct _gss_context *) context_handle;
+       gssapi_mech_interface m;
+
+       if (minor_status)
+           *minor_status = 0;
+       if (conf_state)
+           *conf_state = 0;
+       if (ctx == NULL)
+           return GSS_S_NO_CONTEXT;
+       if (iov == NULL && iov_count != 0)
+           return GSS_S_CALL_INACCESSIBLE_READ;
+
+       m = ctx->gc_mech;
+
+       if (m->gm_wrap_iov_length == NULL) {
+           *minor_status = 0;
+           return GSS_S_UNAVAILABLE;
+       }
+
+       return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx,
+                                      conf_req_flag, qop_req, conf_state,
+                                      iov, iov_count);
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_release_iov_buffer(OM_uint32 *minor_status,
+                      gss_iov_buffer_desc *iov,
+                      int iov_count)
+{
+    OM_uint32 junk;
+    size_t i;
+
+    if (minor_status)
+       *minor_status = 0;
+    if (iov == NULL && iov_count != 0)
+       return GSS_S_CALL_INACCESSIBLE_READ;
+
+    for (i = 0; i < iov_count; i++) {
+       if (iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED)
+           continue;
+       gss_release_buffer(&junk, &iov[i].buffer);
+    }
+    return GSS_S_COMPLETE;
+}
+
+/**
+ * Query the context for parameters.
+ *
+ * SSPI equivalent if this function is QueryContextAttributes.
+ *
+ * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes.
+ */
+
+static gss_OID_desc gss_c_attr_stream_sizes_desc =
+    {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")};
+
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_ATTR_STREAM_SIZES =
+    &gss_c_attr_stream_sizes_desc;
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_context_query_attributes(OM_uint32 *minor_status,
+                            gss_OID attribute,
+                            void *data,
+                            size_t len)
+{
+    *minor_status = 0;
+
+    if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) {
+       memset(data, 0, len);
+       return GSS_S_COMPLETE;
+    }
+
+    return GSS_S_FAILURE;
+}
index c22e59d0c8480934b0aa06e8d5cd217ba7278e2f..3acc18d77092fc4ae0200b87d3fb9b2ec2b1afc2 100644 (file)
@@ -135,6 +135,7 @@ $(eval $(call heimdal_proto_header_template, \
 ))
 
 HEIMDAL_GSSAPI_KRB5_OBJ_FILES = \
+       $(heimdalsrcdir)/lib/gssapi/krb5/aeap.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/copy_ccache.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/delete_sec_context.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/init_sec_context.o \
@@ -192,6 +193,7 @@ HEIMDAL_GSSAPI_OBJ_FILES = \
        $(HEIMDAL_GSSAPI_SPNEGO_OBJ_FILES) \
        $(HEIMDAL_GSSAPI_KRB5_OBJ_FILES) \
        $(heimdalsrcdir)/lib/gssapi/mech/context.o \
+       $(heimdalsrcdir)/lib/gssapi/mech/gss_aeap.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_krb5.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_mech_switch.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_process_context_token.o \