heimdal: add gss_wrap_ex() infrastructure
authorStefan Metzmacher <metze@samba.org>
Fri, 25 Jul 2008 07:03:36 +0000 (09:03 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 18 Aug 2008 06:49:02 +0000 (08:49 +0200)
The start was from Andrew Bartlett,
but I added missing stuff and made it work
correctly.

It also changed the prototypes to do inplace
decryption of the message_buffer.

metze

source/heimdal/lib/gssapi/gssapi/gssapi.h
source/heimdal/lib/gssapi/gssapi_mech.h
source/heimdal/lib/gssapi/krb5/external.c
source/heimdal/lib/gssapi/mech/gss_unwrap_ex.c [new file with mode: 0644]
source/heimdal/lib/gssapi/mech/gss_wrap_ex.c [new file with mode: 0644]
source/heimdal/lib/gssapi/spnego/context_stubs.c
source/heimdal/lib/gssapi/spnego/external.c
source/heimdal/lib/gssapi/spnego/spnego-private.h
source/heimdal_build/internal.mk

index 63f66f73133e2ec1d8883cd46ea23f242cb756bd..738aa9ed157007aa6dcd6c5bdd19077d466cb9e8 100644 (file)
@@ -496,6 +496,27 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap
             gss_qop_t * /*qop_state*/
            );
 
+OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_ex
+           (OM_uint32 *,            /* minor_status */
+            const gss_ctx_id_t,     /* context_handle */
+            int,                    /* conf_req_flag */
+            gss_qop_t,              /* qop_req */
+            const gss_buffer_t,     /* associated_data_buffer */
+            gss_buffer_t,           /* message_buffer */
+            gss_buffer_t,           /* output_token_buffer */
+            int *                   /* conf_state */
+           );
+
+OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap_ex
+           (OM_uint32 *,            /* minor_status */
+            const gss_ctx_id_t,     /* context_handle */
+            const gss_buffer_t,     /* token_header_buffer */
+            const gss_buffer_t,     /* associated_data_buffer */
+            gss_buffer_t,           /* message_buffer */
+            int *,                  /* conf_state */
+            gss_qop_t *             /* qop_state */
+           );
+
 OM_uint32 GSSAPI_LIB_FUNCTION gss_display_status
            (OM_uint32 * /*minor_status*/,
             OM_uint32 /*status_value*/,
index b360de13fcaf53192de49fc62d6c719ef72610cb..6e7af197ed08fc6359cddc0bb498ce895110e3f2 100644 (file)
@@ -132,6 +132,27 @@ typedef OM_uint32 _gss_unwrap_t
               gss_qop_t *             /* qop_state */
              );
 
+typedef OM_uint32 _gss_wrap_ex_t
+             (OM_uint32 *,            /* minor_status */
+              const gss_ctx_id_t,     /* context_handle */
+              int,                    /* conf_req_flag */
+              gss_qop_t,              /* qop_req */
+              const gss_buffer_t,     /* associated_data_buffer */
+              gss_buffer_t,           /* message_buffer */
+              gss_buffer_t,           /* output_token_buffer */
+              int *                   /* conf_state */
+             );
+
+typedef OM_uint32 _gss_unwrap_ex_t
+             (OM_uint32 *,            /* minor_status */
+              const gss_ctx_id_t,     /* context_handle */
+              const gss_buffer_t,     /* token_header_buffer */
+              const gss_buffer_t,     /* associated_data_buffer */
+              gss_buffer_t,           /* message_buffer */
+              int *,                  /* conf_state */
+              gss_qop_t *             /* qop_state */
+             );
+
 typedef OM_uint32 _gss_display_status_t
              (OM_uint32 *,            /* minor_status */
               OM_uint32,              /* status_value */
@@ -324,6 +345,8 @@ typedef struct gssapi_mech_interface_desc {
        _gss_verify_mic_t               *gm_verify_mic;
        _gss_wrap_t                     *gm_wrap;
        _gss_unwrap_t                   *gm_unwrap;
+       _gss_wrap_ex_t                  *gm_wrap_ex;
+       _gss_unwrap_ex_t                *gm_unwrap_ex;
        _gss_display_status_t           *gm_display_status;
        _gss_indicate_mechs_t           *gm_indicate_mechs;
        _gss_compare_name_t             *gm_compare_name;
index 2ee018708a536f583b9f66167d6ab9f78f2ca192..d3e0e2bdb16b869d8d9cd9cf976c3f4d0470515f 100644 (file)
@@ -440,6 +440,8 @@ static gssapi_mech_interface_desc krb5_mech = {
     _gsskrb5_verify_mic,
     _gsskrb5_wrap,
     _gsskrb5_unwrap,
+    NULL,
+    NULL,
     _gsskrb5_display_status,
     _gsskrb5_indicate_mechs,
     _gsskrb5_compare_name,
diff --git a/source/heimdal/lib/gssapi/mech/gss_unwrap_ex.c b/source/heimdal/lib/gssapi/mech/gss_unwrap_ex.c
new file mode 100644 (file)
index 0000000..048afc8
--- /dev/null
@@ -0,0 +1,146 @@
+/* #ident  "@(#)gss_unseal.c 1.10     95/08/07 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ * Copyright 2008 by Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ *  glue routine gss_unwrap
+ */
+
+#include "mech_locl.h"
+
+RCSID("$Id: g_unwrap.c,v 1.1.2.1 2005/01/12 07:04:02 lukeh Exp $");
+
+/*
+ * GSS_Unwrap() with support for associated data.
+ *
+ * Notes:
+ *
+ *      token_header_buffer contains the GSS-API token as
+ *      received from the peer
+ *
+ *      associated_data_buffer contains the complete data
+ *      over which the checksum is to be verified;
+ *
+ *      message_buffer contains the complete data to
+ *      be decrypted if confidentiality was requested;
+ *
+ *      message_buffer value must point into the value
+ *      of associated_data_buffer (hence input_message_buffer
+ *      just specifies a span within associated_data_buffer).
+ *
+ *      associated_data_buffer will have been authenticated
+ *
+ */
+static OM_uint32 generic_unwrap_ex
+          (OM_uint32 * minor_status,
+           const gss_ctx_id_t context_handle,
+           const gss_buffer_t token_header_buffer,
+           const gss_buffer_t associated_data_buffer,
+           gss_buffer_t message_buffer,
+           int *conf_state,
+           gss_qop_t *qop_state)
+{
+    OM_uint32          major_status, minor;
+    gss_buffer_desc unwrap_buffer;
+    gss_buffer_desc output_buffer;
+    
+    unwrap_buffer.length = token_header_buffer->length +
+           message_buffer->length;
+    unwrap_buffer.value = malloc(unwrap_buffer.length);
+    if (unwrap_buffer.value == NULL) {
+           *minor_status = ENOMEM;
+           return GSS_S_FAILURE;
+    }
+    memcpy(unwrap_buffer.value, token_header_buffer->value,
+          token_header_buffer->length);
+    memcpy((u_char *)unwrap_buffer.value + token_header_buffer->length,
+          message_buffer->value,
+          message_buffer->length);
+    
+    major_status = gss_unwrap(minor_status,
+                             context_handle,
+                             &unwrap_buffer,
+                             &output_buffer,
+                             conf_state,
+                             qop_state);
+    if (major_status != GSS_S_COMPLETE) {
+           gss_release_buffer(&minor, &unwrap_buffer);
+           return major_status;
+    }
+
+    if (output_buffer.length != message_buffer->length) {
+           gss_release_buffer(&minor, &unwrap_buffer);
+           gss_release_buffer(&minor, &output_buffer);
+           *minor_status = EINVAL;
+           return GSS_S_FAILURE;
+    }
+
+    memcpy(message_buffer->value,
+          output_buffer.value,
+          output_buffer.length);
+    
+    gss_release_buffer(&minor, &unwrap_buffer);
+    gss_release_buffer(&minor, &output_buffer);
+
+    return major_status;
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_unwrap_ex (OM_uint32 *minor_status,
+              const gss_ctx_id_t context_handle,
+              const gss_buffer_t token_header_buffer,
+              const gss_buffer_t associated_data_buffer,
+              gss_buffer_t message_buffer,
+              int *conf_state,
+              gss_qop_t *qop_state)
+{
+    OM_uint32          status;
+    struct _gss_context *ctx = (struct _gss_context *) context_handle;
+    gssapi_mech_interface m = ctx->gc_mech;
+
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+
+    if (m->gm_unwrap_ex != NULL)
+        status = (m->gm_unwrap_ex)(minor_status,
+                                     ctx->gc_ctx,
+                                     token_header_buffer,
+                                     associated_data_buffer,
+                                     message_buffer,
+                                     conf_state,
+                                     qop_state);
+    else
+        status = generic_unwrap_ex(minor_status,
+                                  context_handle,
+                                  token_header_buffer,
+                                  associated_data_buffer,
+                                  message_buffer,
+                                  conf_state,
+                                  qop_state);
+
+    return status;
+}
+
diff --git a/source/heimdal/lib/gssapi/mech/gss_wrap_ex.c b/source/heimdal/lib/gssapi/mech/gss_wrap_ex.c
new file mode 100644 (file)
index 0000000..af393fd
--- /dev/null
@@ -0,0 +1,128 @@
+/* #ident  "@(#)gss_seal.c 1.10     95/08/07 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ * Copyright 2008 by Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ *  glue routine for gss_wrap_ex
+ */
+
+#include "mech_locl.h"
+
+RCSID("$Id: g_wrap.c,v 1.1.2.1 2005/01/12 07:04:02 lukeh Exp $");
+
+/*
+ * GSS_Wrap() with support for associated data.
+ *
+ * Notes:
+ *
+ *      associated_data_buffer contains the complete data
+ *      over which the checksum is to be verified;
+ *
+ *      message_buffer contains the data to be
+ *      encrypted if conf_req_flag == TRUE.
+ *
+ *      On returning GSS_S_COMPLETE, output_token_buffer
+ *      will contain the GSS-API tokenheader, and;
+ *
+ */
+
+static OM_uint32 generic_wrap_ex(OM_uint32 * minor_status,
+                                const gss_ctx_id_t context_handle,
+                                int conf_req_flag,
+                                gss_qop_t qop_req,
+                                const gss_buffer_t associated_data_buffer,
+                                gss_buffer_t message_buffer,
+                                gss_buffer_t output_token_buffer,
+                                int * conf_state
+       )
+{
+    OM_uint32          major_status, minor;
+
+    gss_buffer_desc wrap_buffer;
+    OM_uint32 token_header_size;
+
+    major_status = gss_wrap(minor_status,
+                           context_handle,
+                           conf_req_flag,
+                           qop_req,
+                           message_buffer,
+                           conf_state,
+                           &wrap_buffer);
+    if (major_status != GSS_S_COMPLETE) {
+           return major_status;
+    }
+    
+    token_header_size = wrap_buffer.length - message_buffer->length;
+    
+    memcpy(message_buffer->value,
+          (u_char *)wrap_buffer.value + token_header_size,
+          message_buffer->length);
+
+    output_token_buffer->length = token_header_size;
+    output_token_buffer->value = realloc(wrap_buffer.value, token_header_size);
+    if (output_token_buffer->value == NULL) {
+         gss_release_buffer(&minor, &wrap_buffer);
+         *minor_status = ENOMEM;
+        return GSS_S_FAILURE;
+    }
+    
+    return major_status;
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_ex (OM_uint32 *minor_status,
+            const gss_ctx_id_t context_handle,
+            int conf_req_flag,
+            gss_qop_t qop_req,
+            const gss_buffer_t associated_data_buffer,
+            gss_buffer_t message_buffer,
+            gss_buffer_t output_token_buffer,
+            int *conf_state)
+{
+    OM_uint32          status;
+    struct _gss_context *ctx = (struct _gss_context *) context_handle;
+    gssapi_mech_interface m = ctx->gc_mech;
+    
+    if (m->gm_wrap_ex != NULL)
+        status = (m->gm_wrap_ex)(minor_status,
+                                ctx->gc_ctx,
+                                conf_req_flag,
+                                qop_req,
+                                associated_data_buffer,
+                                message_buffer,
+                                output_token_buffer,
+                                conf_state);
+    else
+       status = generic_wrap_ex(minor_status,
+                                context_handle,
+                                conf_req_flag,
+                                qop_req,
+                                associated_data_buffer,
+                                message_buffer,
+                                output_token_buffer,
+                                conf_state);
+
+    return status;
+}
+
index 6f1c3eb4b6f493e4050c46e0ff5b3b007a5f82a6..aa6e43eabf3d06b8fb88a262857f5441205f3ac8 100644 (file)
@@ -263,6 +263,74 @@ OM_uint32 _gss_spnego_unwrap
                      qop_state);
 }
 
+OM_uint32 _gss_spnego_wrap_ex
+           (OM_uint32 * minor_status,
+            const gss_ctx_id_t context_handle,
+            int conf_req_flag,
+            gss_qop_t qop_req,
+           const gss_buffer_t associated_data_buffer,
+            gss_buffer_t message_buffer,
+           gss_buffer_t output_token_buffer,
+            int * conf_state
+           )
+{
+    gssspnego_ctx ctx;
+
+    *minor_status = 0;
+
+    if (context_handle == GSS_C_NO_CONTEXT) {
+       return GSS_S_NO_CONTEXT;
+    }
+
+    ctx = (gssspnego_ctx)context_handle;
+
+    if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+       return GSS_S_NO_CONTEXT;
+    }
+
+    return gss_wrap_ex(minor_status,
+                      ctx->negotiated_ctx_id,
+                      conf_req_flag,
+                      qop_req,
+                      associated_data_buffer,
+                      message_buffer,
+                      output_token_buffer,
+                      conf_state);
+}
+
+OM_uint32 _gss_spnego_unwrap_ex
+           (OM_uint32 * minor_status,
+            const gss_ctx_id_t context_handle,
+           const gss_buffer_t token_header_buffer,
+           const gss_buffer_t associated_data_buffer,
+            gss_buffer_t message_buffer,
+            int * conf_state,
+            gss_qop_t * qop_state
+           )
+{
+    gssspnego_ctx ctx;
+
+    *minor_status = 0;
+
+    if (context_handle == GSS_C_NO_CONTEXT) {
+       return GSS_S_NO_CONTEXT;
+    }
+
+    ctx = (gssspnego_ctx)context_handle;
+
+    if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+       return GSS_S_NO_CONTEXT;
+    }
+
+    return gss_unwrap_ex(minor_status,
+                        ctx->negotiated_ctx_id,
+                        token_header_buffer,
+                        associated_data_buffer,
+                        message_buffer,
+                        conf_state,
+                        qop_state);
+}
+
 OM_uint32 _gss_spnego_compare_name
            (OM_uint32 *minor_status,
             const gss_name_t name1,
index 317d358707269c92a67f625c5061dbae29401c38..a2f8b3c7f7dcfaf1049af255c100d8789e563066 100644 (file)
@@ -57,6 +57,8 @@ static gssapi_mech_interface_desc spnego_mech = {
     _gss_spnego_verify_mic,
     _gss_spnego_wrap,
     _gss_spnego_unwrap,
+    _gss_spnego_wrap_ex,
+    _gss_spnego_unwrap_ex,
     NULL, /* gm_display_status */
     NULL, /* gm_indicate_mechs */
     _gss_spnego_compare_name,
index 3b20d737b72adf8bc87aaaa5096e02f56f6e2bb9..be4449e0fda3531153610c43942a98c90742aa62 100644 (file)
@@ -325,6 +325,27 @@ _gss_spnego_wrap (
        int * /*conf_state*/,
        gss_buffer_t output_message_buffer );
 
+OM_uint32
+_gss_spnego_wrap_ex (
+       OM_uint32 * /*minor_status*/,
+       const gss_ctx_id_t /*context_handle*/,
+       int /*conf_req_flag*/,
+       gss_qop_t /*qop_req*/,
+       const gss_buffer_t /*associated_data_buffer*/,
+       gss_buffer_t /*message_buffer*/,
+       gss_buffer_t /*output_token_buffer*/,
+       int * conf_state );
+
+OM_uint32
+_gss_spnego_unwrap_ex (
+       OM_uint32 * /*minor_status*/,
+       const gss_ctx_id_t /*context_handle*/,
+       const gss_buffer_t /*token_header_buffer*/,
+       const gss_buffer_t /*associated_data_buffer*/,
+       gss_buffer_t /*message_buffer*/,
+       int * /*conf_state*/,
+       gss_qop_t * qop_state );
+
 OM_uint32
 _gss_spnego_wrap_size_limit (
         OM_uint32 * /*minor_status*/,
index 8c576bd2c6a29b540fd9d6572f338b161cd1ce90..f8bb2ca60a8b5ae9905f1f2494b0043dd35a8a93 100644 (file)
@@ -115,9 +115,11 @@ HEIMDAL_GSSAPI_OBJ_FILES = \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_import_sec_context.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_inquire_cred.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_wrap.o \
+       $(heimdalsrcdir)/lib/gssapi/mech/gss_wrap_ex.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_import_name.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_duplicate_name.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_unwrap.o \
+       $(heimdalsrcdir)/lib/gssapi/mech/gss_unwrap_ex.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_export_sec_context.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_inquire_context.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_release_name.o \