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 /* EXPORT DELETE START */
  87 
  88         OM_uint32               status;
  89         gss_union_ctx_id_t      ctx;
  90         gss_mechanism           mech;
  91 
  92         status = val_seal_args(minor_status,
  93                         context_handle,
  94                         input_message_buffer,
  95                         output_message_buffer);
  96         if (status != GSS_S_COMPLETE)
  97                 return (status);
  98 
  99         /*
 100          * select the approprate underlying mechanism routine and
 101          * call it.
 102          */
 103 
 104         ctx = (gss_union_ctx_id_t) context_handle;
 105         mech = __gss_get_mechanism(ctx->mech_type);
 106 
 107         if (mech) {
 108                 if (mech->gss_seal) {
 109                         status = mech->gss_seal(
 110                                                 mech->context,
 111                                                 minor_status,
 112                                                 ctx->internal_ctx_id,
 113                                                 conf_req_flag,
 114                                                 qop_req,
 115                                                 input_message_buffer,
 116                                                 conf_state,
 117                                                 output_message_buffer);
 118                         if (status != GSS_S_COMPLETE)
 119                                 map_error(minor_status, mech);
 120                 } else
 121                         status = GSS_S_UNAVAILABLE;
 122 
 123                 return (status);
 124         }
 125 /* EXPORT DELETE END */
 126 
 127         return (GSS_S_BAD_MECH);
 128 }
 129 
 130 OM_uint32
 131 gss_wrap(minor_status,
 132                 context_handle,
 133                 conf_req_flag,
 134                 qop_req,
 135                 input_message_buffer,
 136                 conf_state,
 137                 output_message_buffer)
 138 
 139 OM_uint32 *                     minor_status;
 140 const gss_ctx_id_t              context_handle;
 141 int                             conf_req_flag;
 142 gss_qop_t                       qop_req;
 143 const gss_buffer_t              input_message_buffer;
 144 int *                           conf_state;
 145 gss_buffer_t                    output_message_buffer;
 146 
 147 {
 148         return gss_seal(minor_status, (gss_ctx_id_t)context_handle,
 149                         conf_req_flag, (int) qop_req,
 150                         (gss_buffer_t)input_message_buffer, conf_state,
 151                         output_message_buffer);
 152 }
 153 
 154 /*
 155  * New for V2
 156  */
 157 OM_uint32
 158 gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
 159                                 qop_req, req_output_size, max_input_size)
 160         OM_uint32               *minor_status;
 161         const gss_ctx_id_t      context_handle;
 162         int                     conf_req_flag;
 163         gss_qop_t               qop_req;
 164         OM_uint32               req_output_size;
 165         OM_uint32               *max_input_size;
 166 {
 167         gss_union_ctx_id_t      ctx;
 168         gss_mechanism           mech;
 169         OM_uint32         major_status;
 170 
 171         if (minor_status == NULL)
 172                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
 173         *minor_status = 0;
 174 
 175         if (context_handle == GSS_C_NO_CONTEXT)
 176                 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
 177 
 178         if (max_input_size == NULL)
 179                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
 180 
 181         /*
 182          * select the approprate underlying mechanism routine and
 183          * call it.
 184          */
 185 
 186         ctx = (gss_union_ctx_id_t) context_handle;
 187         mech = __gss_get_mechanism(ctx->mech_type);
 188 
 189         if (!mech)
 190                 return (GSS_S_BAD_MECH);
 191 
 192         if (mech->gss_wrap_size_limit)
 193                 major_status = mech->gss_wrap_size_limit(mech->context,
 194                                                         minor_status,
 195                                                         ctx->internal_ctx_id,
 196                                                         conf_req_flag, qop_req,
 197                                                         req_output_size,
 198                                                         max_input_size);
 199         else
 200                 major_status = GSS_S_UNAVAILABLE;
 201         if (major_status != GSS_S_COMPLETE)
 202                 map_error(minor_status, mech);
 203         return major_status;
 204 }