1 /* #pragma ident "@(#)g_seal.c 1.19 98/04/21 SMI" */
2
3 /*
4 * Copyright 1996 by Sun Microsystems, Inc.
5 *
6 * Permission to use, copy, modify, distribute, and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appears in all copies and
9 * that both that copyright notice and this permission notice appear in
10 * supporting documentation, and that the name of Sun Microsystems not be used
11 * in advertising or publicity pertaining to distribution of the software
12 * without specific, written prior permission. Sun Microsystems makes no
13 * representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied warranty.
15 *
16 * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25 /*
26 * glue routine for gss_unwrap_aead
27 */
28
29 #include "mglueP.h"
30
31 static OM_uint32
val_unwrap_aead_args(OM_uint32 * minor_status,gss_ctx_id_t context_handle,gss_buffer_t input_message_buffer,gss_buffer_t input_assoc_buffer,gss_buffer_t output_payload_buffer,int * conf_state,gss_qop_t * qop_state)32 val_unwrap_aead_args(
33 OM_uint32 *minor_status,
34 gss_ctx_id_t context_handle,
35 gss_buffer_t input_message_buffer,
36 gss_buffer_t input_assoc_buffer,
37 gss_buffer_t output_payload_buffer,
38 int *conf_state,
39 gss_qop_t *qop_state)
40 {
41
42 /* Initialize outputs. */
43
44 if (minor_status != NULL)
45 *minor_status = 0;
46
47 /* Validate arguments. */
48
49 if (minor_status == NULL)
50 return (GSS_S_CALL_INACCESSIBLE_WRITE);
51
52 if (context_handle == GSS_C_NO_CONTEXT)
53 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
54
55 if (input_message_buffer == GSS_C_NO_BUFFER)
56 return (GSS_S_CALL_INACCESSIBLE_READ);
57
58 if (output_payload_buffer == GSS_C_NO_BUFFER)
59 return (GSS_S_CALL_INACCESSIBLE_WRITE);
60
61 return (GSS_S_COMPLETE);
62 }
63
64 static OM_uint32
gssint_unwrap_aead_iov_shim(gss_mechanism mech,OM_uint32 * minor_status,gss_ctx_id_t context_handle,gss_buffer_t input_message_buffer,gss_buffer_t input_assoc_buffer,gss_buffer_t output_payload_buffer,int * conf_state,gss_qop_t * qop_state)65 gssint_unwrap_aead_iov_shim(gss_mechanism mech,
66 OM_uint32 *minor_status,
67 gss_ctx_id_t context_handle,
68 gss_buffer_t input_message_buffer,
69 gss_buffer_t input_assoc_buffer,
70 gss_buffer_t output_payload_buffer,
71 int *conf_state,
72 gss_qop_t *qop_state)
73 {
74 OM_uint32 status;
75 gss_iov_buffer_desc iov[3];
76 int i = 0;
77
78 iov[i].type = GSS_IOV_BUFFER_TYPE_STREAM;
79 iov[i].buffer = *input_message_buffer;
80 i++;
81
82 if (input_assoc_buffer != NULL) {
83 iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
84 iov[i].buffer = *input_assoc_buffer;
85 i++;
86 }
87
88 iov[i].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;
89 iov[i].buffer.value = NULL;
90 iov[i].buffer.length = 0;
91 i++;
92
93 assert(mech->gss_unwrap_iov);
94
95 status = mech->gss_unwrap_iov(minor_status, context_handle, conf_state,
96 qop_state, iov, i);
97 if (status == GSS_S_COMPLETE) {
98 *output_payload_buffer = iov[i - 1].buffer;
99 } else {
100 OM_uint32 minor;
101
102 map_error(minor_status, mech);
103
104 if (iov[i - 1].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) {
105 gss_release_buffer(&minor, &iov[i - 1].buffer);
106 iov[i - 1].type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED);
107 }
108 }
109
110 return status;
111 }
112
113 OM_uint32
gssint_unwrap_aead(gss_mechanism mech,OM_uint32 * minor_status,gss_union_ctx_id_t ctx,gss_buffer_t input_message_buffer,gss_buffer_t input_assoc_buffer,gss_buffer_t output_payload_buffer,int * conf_state,gss_qop_t * qop_state)114 gssint_unwrap_aead (gss_mechanism mech,
115 OM_uint32 *minor_status,
116 gss_union_ctx_id_t ctx,
117 gss_buffer_t input_message_buffer,
118 gss_buffer_t input_assoc_buffer,
119 gss_buffer_t output_payload_buffer,
120 int *conf_state,
121 gss_qop_t *qop_state)
122 {
123 OM_uint32 status;
124
125 assert(mech != NULL);
126 assert(ctx != NULL);
127
128 /* EXPORT DELETE START */
129
130 if (mech->gss_unwrap_aead) {
131 status = mech->gss_unwrap_aead(minor_status,
132 ctx->internal_ctx_id,
133 input_message_buffer,
134 input_assoc_buffer,
135 output_payload_buffer,
136 conf_state,
137 qop_state);
138 if (status != GSS_S_COMPLETE)
139 map_error(minor_status, mech);
140 } else if (mech->gss_unwrap_iov) {
141 status = gssint_unwrap_aead_iov_shim(mech,
142 minor_status,
143 ctx->internal_ctx_id,
144 input_message_buffer,
145 input_assoc_buffer,
146 output_payload_buffer,
147 conf_state,
148 qop_state);
149 } else
150 status = GSS_S_UNAVAILABLE;
151 /* EXPORT DELETE END */
152
153 return (status);
154 }
155
156 OM_uint32 KRB5_CALLCONV
gss_unwrap_aead(minor_status,context_handle,input_message_buffer,input_assoc_buffer,output_payload_buffer,conf_state,qop_state)157 gss_unwrap_aead (minor_status,
158 context_handle,
159 input_message_buffer,
160 input_assoc_buffer,
161 output_payload_buffer,
162 conf_state,
163 qop_state)
164 OM_uint32 * minor_status;
165 gss_ctx_id_t context_handle;
166 gss_buffer_t input_message_buffer;
167 gss_buffer_t input_assoc_buffer;
168 gss_buffer_t output_payload_buffer;
169 int *conf_state;
170 gss_qop_t *qop_state;
171 {
172
173 OM_uint32 status;
174 gss_union_ctx_id_t ctx;
175 gss_mechanism mech;
176
177 status = val_unwrap_aead_args(minor_status, context_handle,
178 input_message_buffer, input_assoc_buffer,
179 output_payload_buffer,
180 conf_state, qop_state);
181 if (status != GSS_S_COMPLETE)
182 return (status);
183
184 /*
185 * select the approprate underlying mechanism routine and
186 * call it.
187 */
188 ctx = (gss_union_ctx_id_t) context_handle;
189 if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
190 return (GSS_S_NO_CONTEXT);
191 mech = gssint_get_mechanism (ctx->mech_type);
192
193 if (!mech)
194 return (GSS_S_BAD_MECH);
195
196 return gssint_unwrap_aead(mech, minor_status, ctx,
197 input_message_buffer, input_assoc_buffer,
198 output_payload_buffer, conf_state, qop_state);
199 }
200