1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  *  glue routine for gss_seal
  27  */
  28 
  29 #include <mechglueP.h>
  30 #include "gssapiP_generic.h"
  31 
  32 
  33 static OM_uint32
  34 val_seal_args(
  35         OM_uint32 *minor_status,
  36         gss_ctx_id_t context_handle,
  37         gss_buffer_t input_message_buffer,
  38         gss_buffer_t output_message_buffer)
  39 {
  40 
  41         /* Initialize outputs. */
  42 
  43         if (minor_status != NULL)
  44                 *minor_status = 0;
  45 
  46         if (output_message_buffer != GSS_C_NO_BUFFER) {
  47                 output_message_buffer->length = 0;
  48                 output_message_buffer->value = NULL;
  49         }
  50 
  51         /* Validate arguments. */
  52 
  53         if (minor_status == NULL)
  54                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
  55 
  56         if (context_handle == GSS_C_NO_CONTEXT)
  57                 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
  58 
  59         if (input_message_buffer == GSS_C_NO_BUFFER)
  60                 return (GSS_S_CALL_INACCESSIBLE_READ);
  61 
  62         if (output_message_buffer == GSS_C_NO_BUFFER)
  63                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
  64 
  65         return (GSS_S_COMPLETE);
  66 }
  67 
  68 /*ARGSUSED*/
  69 OM_uint32
  70 gss_seal(minor_status,
  71                 context_handle,
  72                 conf_req_flag,
  73                 qop_req,
  74                 input_message_buffer,
  75                 conf_state,
  76                 output_message_buffer)
  77 
  78 OM_uint32 *                     minor_status;
  79 gss_ctx_id_t                    context_handle;
  80 int                             conf_req_flag;
  81 int                             qop_req;
  82 gss_buffer_t                    input_message_buffer;
  83 int *                           conf_state;
  84 gss_buffer_t                    output_message_buffer;
  85 {
  86         OM_uint32               status;
  87         gss_union_ctx_id_t      ctx;
  88         gss_mechanism           mech;
  89 
  90         status = val_seal_args(minor_status,
  91                         context_handle,
  92                         input_message_buffer,
  93                         output_message_buffer);
  94         if (status != GSS_S_COMPLETE)
  95                 return (status);
  96 
  97         /*
  98          * select the approprate underlying mechanism routine and
  99          * call it.
 100          */
 101 
 102         ctx = (gss_union_ctx_id_t) context_handle;
 103         mech = __gss_get_mechanism(ctx->mech_type);
 104 
 105         if (mech) {
 106                 if (mech->gss_seal) {
 107                         status = mech->gss_seal(
 108                                                 mech->context,
 109                                                 minor_status,
 110                                                 ctx->internal_ctx_id,
 111                                                 conf_req_flag,
 112                                                 qop_req,
 113                                                 input_message_buffer,
 114                                                 conf_state,
 115                                                 output_message_buffer);
 116                         if (status != GSS_S_COMPLETE)
 117                                 map_error(minor_status, mech);
 118                 } else
 119                         status = GSS_S_UNAVAILABLE;
 120 
 121                 return (status);
 122         }
 123 
 124         return (GSS_S_BAD_MECH);
 125 }
 126 
 127 OM_uint32
 128 gss_wrap(minor_status,
 129                 context_handle,
 130                 conf_req_flag,
 131                 qop_req,
 132                 input_message_buffer,
 133                 conf_state,
 134                 output_message_buffer)
 135 
 136 OM_uint32 *                     minor_status;
 137 const gss_ctx_id_t              context_handle;
 138 int                             conf_req_flag;
 139 gss_qop_t                       qop_req;
 140 const gss_buffer_t              input_message_buffer;
 141 int *                           conf_state;
 142 gss_buffer_t                    output_message_buffer;
 143 
 144 {
 145         return gss_seal(minor_status, (gss_ctx_id_t)context_handle,
 146                         conf_req_flag, (int) qop_req,
 147                         (gss_buffer_t)input_message_buffer, conf_state,
 148                         output_message_buffer);
 149 }
 150 
 151 /*
 152  * New for V2
 153  */
 154 OM_uint32
 155 gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
 156                                 qop_req, req_output_size, max_input_size)
 157         OM_uint32               *minor_status;
 158         const gss_ctx_id_t      context_handle;
 159         int                     conf_req_flag;
 160         gss_qop_t               qop_req;
 161         OM_uint32               req_output_size;
 162         OM_uint32               *max_input_size;
 163 {
 164         gss_union_ctx_id_t      ctx;
 165         gss_mechanism           mech;
 166         OM_uint32         major_status;
 167 
 168         if (minor_status == NULL)
 169                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
 170         *minor_status = 0;
 171 
 172         if (context_handle == GSS_C_NO_CONTEXT)
 173                 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
 174 
 175         if (max_input_size == NULL)
 176                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
 177 
 178         /*
 179          * select the approprate underlying mechanism routine and
 180          * call it.
 181          */
 182 
 183         ctx = (gss_union_ctx_id_t) context_handle;
 184         mech = __gss_get_mechanism(ctx->mech_type);
 185 
 186         if (!mech)
 187                 return (GSS_S_BAD_MECH);
 188 
 189         if (mech->gss_wrap_size_limit)
 190                 major_status = mech->gss_wrap_size_limit(mech->context,
 191                                                         minor_status,
 192                                                         ctx->internal_ctx_id,
 193                                                         conf_req_flag, qop_req,
 194                                                         req_output_size,
 195                                                         max_input_size);
 196         else
 197                 major_status = GSS_S_UNAVAILABLE;
 198         if (major_status != GSS_S_COMPLETE)
 199                 map_error(minor_status, mech);
 200         return major_status;
 201 }