xref: /freebsd/crypto/heimdal/lib/gssapi/spnego/context_stubs.c (revision c19800e8cd5640693f36f2040db4ab5e8d738146)
1c19800e8SDoug Rabson /*
2c19800e8SDoug Rabson  * Copyright (c) 2004, PADL Software Pty Ltd.
3c19800e8SDoug Rabson  * All rights reserved.
4c19800e8SDoug Rabson  *
5c19800e8SDoug Rabson  * Redistribution and use in source and binary forms, with or without
6c19800e8SDoug Rabson  * modification, are permitted provided that the following conditions
7c19800e8SDoug Rabson  * are met:
8c19800e8SDoug Rabson  *
9c19800e8SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
10c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
11c19800e8SDoug Rabson  *
12c19800e8SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
13c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
14c19800e8SDoug Rabson  *    documentation and/or other materials provided with the distribution.
15c19800e8SDoug Rabson  *
16c19800e8SDoug Rabson  * 3. Neither the name of PADL Software nor the names of its contributors
17c19800e8SDoug Rabson  *    may be used to endorse or promote products derived from this software
18c19800e8SDoug Rabson  *    without specific prior written permission.
19c19800e8SDoug Rabson  *
20c19800e8SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21c19800e8SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c19800e8SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c19800e8SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24c19800e8SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c19800e8SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c19800e8SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c19800e8SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c19800e8SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c19800e8SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c19800e8SDoug Rabson  * SUCH DAMAGE.
31c19800e8SDoug Rabson  */
32c19800e8SDoug Rabson 
33c19800e8SDoug Rabson #include "spnego/spnego_locl.h"
34c19800e8SDoug Rabson 
35c19800e8SDoug Rabson RCSID("$Id: context_stubs.c 21035 2007-06-09 15:32:47Z lha $");
36c19800e8SDoug Rabson 
37c19800e8SDoug Rabson static OM_uint32
38c19800e8SDoug Rabson spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
39c19800e8SDoug Rabson {
40c19800e8SDoug Rabson     OM_uint32 ret, junk;
41c19800e8SDoug Rabson     gss_OID_set m;
42c19800e8SDoug Rabson     int i;
43c19800e8SDoug Rabson 
44c19800e8SDoug Rabson     ret = gss_indicate_mechs(minor_status, &m);
45c19800e8SDoug Rabson     if (ret != GSS_S_COMPLETE)
46c19800e8SDoug Rabson 	return ret;
47c19800e8SDoug Rabson 
48c19800e8SDoug Rabson     ret = gss_create_empty_oid_set(minor_status, mechs);
49c19800e8SDoug Rabson     if (ret != GSS_S_COMPLETE) {
50c19800e8SDoug Rabson 	gss_release_oid_set(&junk, &m);
51c19800e8SDoug Rabson 	return ret;
52c19800e8SDoug Rabson     }
53c19800e8SDoug Rabson 
54c19800e8SDoug Rabson     for (i = 0; i < m->count; i++) {
55c19800e8SDoug Rabson 	if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM))
56c19800e8SDoug Rabson 	    continue;
57c19800e8SDoug Rabson 
58c19800e8SDoug Rabson 	ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs);
59c19800e8SDoug Rabson 	if (ret) {
60c19800e8SDoug Rabson 	    gss_release_oid_set(&junk, &m);
61c19800e8SDoug Rabson 	    gss_release_oid_set(&junk, mechs);
62c19800e8SDoug Rabson 	    return ret;
63c19800e8SDoug Rabson 	}
64c19800e8SDoug Rabson     }
65c19800e8SDoug Rabson     return ret;
66c19800e8SDoug Rabson }
67c19800e8SDoug Rabson 
68c19800e8SDoug Rabson 
69c19800e8SDoug Rabson 
70c19800e8SDoug Rabson OM_uint32 _gss_spnego_process_context_token
71c19800e8SDoug Rabson            (OM_uint32 *minor_status,
72c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
73c19800e8SDoug Rabson             const gss_buffer_t token_buffer
74c19800e8SDoug Rabson            )
75c19800e8SDoug Rabson {
76c19800e8SDoug Rabson     gss_ctx_id_t context ;
77c19800e8SDoug Rabson     gssspnego_ctx ctx;
78c19800e8SDoug Rabson     OM_uint32 ret;
79c19800e8SDoug Rabson 
80c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT)
81c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
82c19800e8SDoug Rabson 
83c19800e8SDoug Rabson     context = context_handle;
84c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
85c19800e8SDoug Rabson 
86c19800e8SDoug Rabson     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
87c19800e8SDoug Rabson 
88c19800e8SDoug Rabson     ret = gss_process_context_token(minor_status,
89c19800e8SDoug Rabson 				    ctx->negotiated_ctx_id,
90c19800e8SDoug Rabson 				    token_buffer);
91c19800e8SDoug Rabson     if (ret != GSS_S_COMPLETE) {
92c19800e8SDoug Rabson 	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
93c19800e8SDoug Rabson 	return ret;
94c19800e8SDoug Rabson     }
95c19800e8SDoug Rabson 
96c19800e8SDoug Rabson     ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
97c19800e8SDoug Rabson 
98c19800e8SDoug Rabson     return _gss_spnego_internal_delete_sec_context(minor_status,
99c19800e8SDoug Rabson 					   &context,
100c19800e8SDoug Rabson 					   GSS_C_NO_BUFFER);
101c19800e8SDoug Rabson }
102c19800e8SDoug Rabson 
103c19800e8SDoug Rabson OM_uint32 _gss_spnego_delete_sec_context
104c19800e8SDoug Rabson            (OM_uint32 *minor_status,
105c19800e8SDoug Rabson             gss_ctx_id_t *context_handle,
106c19800e8SDoug Rabson             gss_buffer_t output_token
107c19800e8SDoug Rabson            )
108c19800e8SDoug Rabson {
109c19800e8SDoug Rabson     gssspnego_ctx ctx;
110c19800e8SDoug Rabson 
111c19800e8SDoug Rabson     if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)
112c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
113c19800e8SDoug Rabson 
114c19800e8SDoug Rabson     ctx = (gssspnego_ctx)*context_handle;
115c19800e8SDoug Rabson 
116c19800e8SDoug Rabson     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
117c19800e8SDoug Rabson 
118c19800e8SDoug Rabson     return _gss_spnego_internal_delete_sec_context(minor_status,
119c19800e8SDoug Rabson 						   context_handle,
120c19800e8SDoug Rabson 						   output_token);
121c19800e8SDoug Rabson }
122c19800e8SDoug Rabson 
123c19800e8SDoug Rabson OM_uint32 _gss_spnego_context_time
124c19800e8SDoug Rabson            (OM_uint32 *minor_status,
125c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
126c19800e8SDoug Rabson             OM_uint32 *time_rec
127c19800e8SDoug Rabson            )
128c19800e8SDoug Rabson {
129c19800e8SDoug Rabson     gssspnego_ctx ctx;
130c19800e8SDoug Rabson     *minor_status = 0;
131c19800e8SDoug Rabson 
132c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
133c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
134c19800e8SDoug Rabson     }
135c19800e8SDoug Rabson 
136c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
137c19800e8SDoug Rabson 
138c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
139c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
140c19800e8SDoug Rabson     }
141c19800e8SDoug Rabson 
142c19800e8SDoug Rabson     return gss_context_time(minor_status,
143c19800e8SDoug Rabson 			    ctx->negotiated_ctx_id,
144c19800e8SDoug Rabson 			    time_rec);
145c19800e8SDoug Rabson }
146c19800e8SDoug Rabson 
147c19800e8SDoug Rabson OM_uint32 _gss_spnego_get_mic
148c19800e8SDoug Rabson            (OM_uint32 *minor_status,
149c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
150c19800e8SDoug Rabson             gss_qop_t qop_req,
151c19800e8SDoug Rabson             const gss_buffer_t message_buffer,
152c19800e8SDoug Rabson             gss_buffer_t message_token
153c19800e8SDoug Rabson            )
154c19800e8SDoug Rabson {
155c19800e8SDoug Rabson     gssspnego_ctx ctx;
156c19800e8SDoug Rabson 
157c19800e8SDoug Rabson     *minor_status = 0;
158c19800e8SDoug Rabson 
159c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
160c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
161c19800e8SDoug Rabson     }
162c19800e8SDoug Rabson 
163c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
164c19800e8SDoug Rabson 
165c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
166c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
167c19800e8SDoug Rabson     }
168c19800e8SDoug Rabson 
169c19800e8SDoug Rabson     return gss_get_mic(minor_status, ctx->negotiated_ctx_id,
170c19800e8SDoug Rabson 		       qop_req, message_buffer, message_token);
171c19800e8SDoug Rabson }
172c19800e8SDoug Rabson 
173c19800e8SDoug Rabson OM_uint32 _gss_spnego_verify_mic
174c19800e8SDoug Rabson            (OM_uint32 * minor_status,
175c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
176c19800e8SDoug Rabson             const gss_buffer_t message_buffer,
177c19800e8SDoug Rabson             const gss_buffer_t token_buffer,
178c19800e8SDoug Rabson             gss_qop_t * qop_state
179c19800e8SDoug Rabson            )
180c19800e8SDoug Rabson {
181c19800e8SDoug Rabson     gssspnego_ctx ctx;
182c19800e8SDoug Rabson 
183c19800e8SDoug Rabson     *minor_status = 0;
184c19800e8SDoug Rabson 
185c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
186c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
187c19800e8SDoug Rabson     }
188c19800e8SDoug Rabson 
189c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
190c19800e8SDoug Rabson 
191c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
192c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
193c19800e8SDoug Rabson     }
194c19800e8SDoug Rabson 
195c19800e8SDoug Rabson     return gss_verify_mic(minor_status,
196c19800e8SDoug Rabson 			  ctx->negotiated_ctx_id,
197c19800e8SDoug Rabson 			  message_buffer,
198c19800e8SDoug Rabson 			  token_buffer,
199c19800e8SDoug Rabson 			  qop_state);
200c19800e8SDoug Rabson }
201c19800e8SDoug Rabson 
202c19800e8SDoug Rabson OM_uint32 _gss_spnego_wrap
203c19800e8SDoug Rabson            (OM_uint32 * minor_status,
204c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
205c19800e8SDoug Rabson             int conf_req_flag,
206c19800e8SDoug Rabson             gss_qop_t qop_req,
207c19800e8SDoug Rabson             const gss_buffer_t input_message_buffer,
208c19800e8SDoug Rabson             int * conf_state,
209c19800e8SDoug Rabson             gss_buffer_t output_message_buffer
210c19800e8SDoug Rabson            )
211c19800e8SDoug Rabson {
212c19800e8SDoug Rabson     gssspnego_ctx ctx;
213c19800e8SDoug Rabson 
214c19800e8SDoug Rabson     *minor_status = 0;
215c19800e8SDoug Rabson 
216c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
217c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
218c19800e8SDoug Rabson     }
219c19800e8SDoug Rabson 
220c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
221c19800e8SDoug Rabson 
222c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
223c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
224c19800e8SDoug Rabson     }
225c19800e8SDoug Rabson 
226c19800e8SDoug Rabson     return gss_wrap(minor_status,
227c19800e8SDoug Rabson 		    ctx->negotiated_ctx_id,
228c19800e8SDoug Rabson 		    conf_req_flag,
229c19800e8SDoug Rabson 		    qop_req,
230c19800e8SDoug Rabson 		    input_message_buffer,
231c19800e8SDoug Rabson 		    conf_state,
232c19800e8SDoug Rabson 		    output_message_buffer);
233c19800e8SDoug Rabson }
234c19800e8SDoug Rabson 
235c19800e8SDoug Rabson OM_uint32 _gss_spnego_unwrap
236c19800e8SDoug Rabson            (OM_uint32 * minor_status,
237c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
238c19800e8SDoug Rabson             const gss_buffer_t input_message_buffer,
239c19800e8SDoug Rabson             gss_buffer_t output_message_buffer,
240c19800e8SDoug Rabson             int * conf_state,
241c19800e8SDoug Rabson             gss_qop_t * qop_state
242c19800e8SDoug Rabson            )
243c19800e8SDoug Rabson {
244c19800e8SDoug Rabson     gssspnego_ctx ctx;
245c19800e8SDoug Rabson 
246c19800e8SDoug Rabson     *minor_status = 0;
247c19800e8SDoug Rabson 
248c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
249c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
250c19800e8SDoug Rabson     }
251c19800e8SDoug Rabson 
252c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
253c19800e8SDoug Rabson 
254c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
255c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
256c19800e8SDoug Rabson     }
257c19800e8SDoug Rabson 
258c19800e8SDoug Rabson     return gss_unwrap(minor_status,
259c19800e8SDoug Rabson 		      ctx->negotiated_ctx_id,
260c19800e8SDoug Rabson 		      input_message_buffer,
261c19800e8SDoug Rabson 		      output_message_buffer,
262c19800e8SDoug Rabson 		      conf_state,
263c19800e8SDoug Rabson 		      qop_state);
264c19800e8SDoug Rabson }
265c19800e8SDoug Rabson 
266c19800e8SDoug Rabson OM_uint32 _gss_spnego_display_status
267c19800e8SDoug Rabson            (OM_uint32 * minor_status,
268c19800e8SDoug Rabson             OM_uint32 status_value,
269c19800e8SDoug Rabson             int status_type,
270c19800e8SDoug Rabson             const gss_OID mech_type,
271c19800e8SDoug Rabson             OM_uint32 * message_context,
272c19800e8SDoug Rabson             gss_buffer_t status_string
273c19800e8SDoug Rabson            )
274c19800e8SDoug Rabson {
275c19800e8SDoug Rabson     return GSS_S_FAILURE;
276c19800e8SDoug Rabson }
277c19800e8SDoug Rabson 
278c19800e8SDoug Rabson OM_uint32 _gss_spnego_compare_name
279c19800e8SDoug Rabson            (OM_uint32 *minor_status,
280c19800e8SDoug Rabson             const gss_name_t name1,
281c19800e8SDoug Rabson             const gss_name_t name2,
282c19800e8SDoug Rabson             int * name_equal
283c19800e8SDoug Rabson            )
284c19800e8SDoug Rabson {
285c19800e8SDoug Rabson     spnego_name n1 = (spnego_name)name1;
286c19800e8SDoug Rabson     spnego_name n2 = (spnego_name)name2;
287c19800e8SDoug Rabson 
288c19800e8SDoug Rabson     *name_equal = 0;
289c19800e8SDoug Rabson 
290c19800e8SDoug Rabson     if (!gss_oid_equal(&n1->type, &n2->type))
291c19800e8SDoug Rabson 	return GSS_S_COMPLETE;
292c19800e8SDoug Rabson     if (n1->value.length != n2->value.length)
293c19800e8SDoug Rabson 	return GSS_S_COMPLETE;
294c19800e8SDoug Rabson     if (memcmp(n1->value.value, n2->value.value, n2->value.length) != 0)
295c19800e8SDoug Rabson 	return GSS_S_COMPLETE;
296c19800e8SDoug Rabson 
297c19800e8SDoug Rabson     *name_equal = 1;
298c19800e8SDoug Rabson 
299c19800e8SDoug Rabson     return GSS_S_COMPLETE;
300c19800e8SDoug Rabson }
301c19800e8SDoug Rabson 
302c19800e8SDoug Rabson OM_uint32 _gss_spnego_display_name
303c19800e8SDoug Rabson            (OM_uint32 * minor_status,
304c19800e8SDoug Rabson             const gss_name_t input_name,
305c19800e8SDoug Rabson             gss_buffer_t output_name_buffer,
306c19800e8SDoug Rabson             gss_OID * output_name_type
307c19800e8SDoug Rabson            )
308c19800e8SDoug Rabson {
309c19800e8SDoug Rabson     spnego_name name = (spnego_name)input_name;
310c19800e8SDoug Rabson 
311c19800e8SDoug Rabson     *minor_status = 0;
312c19800e8SDoug Rabson 
313c19800e8SDoug Rabson     if (name == NULL || name->mech == GSS_C_NO_NAME)
314c19800e8SDoug Rabson 	return GSS_S_FAILURE;
315c19800e8SDoug Rabson 
316c19800e8SDoug Rabson     return gss_display_name(minor_status, name->mech,
317c19800e8SDoug Rabson 			    output_name_buffer, output_name_type);
318c19800e8SDoug Rabson }
319c19800e8SDoug Rabson 
320c19800e8SDoug Rabson OM_uint32 _gss_spnego_import_name
321c19800e8SDoug Rabson            (OM_uint32 * minor_status,
322c19800e8SDoug Rabson             const gss_buffer_t name_buffer,
323c19800e8SDoug Rabson             const gss_OID name_type,
324c19800e8SDoug Rabson             gss_name_t * output_name
325c19800e8SDoug Rabson            )
326c19800e8SDoug Rabson {
327c19800e8SDoug Rabson     spnego_name name;
328c19800e8SDoug Rabson     OM_uint32 maj_stat;
329c19800e8SDoug Rabson 
330c19800e8SDoug Rabson     *minor_status = 0;
331c19800e8SDoug Rabson 
332c19800e8SDoug Rabson     name = calloc(1, sizeof(*name));
333c19800e8SDoug Rabson     if (name == NULL) {
334c19800e8SDoug Rabson 	*minor_status = ENOMEM;
335c19800e8SDoug Rabson 	return GSS_S_FAILURE;
336c19800e8SDoug Rabson     }
337c19800e8SDoug Rabson 
338c19800e8SDoug Rabson     maj_stat = _gss_copy_oid(minor_status, name_type, &name->type);
339c19800e8SDoug Rabson     if (maj_stat) {
340c19800e8SDoug Rabson 	free(name);
341c19800e8SDoug Rabson 	return GSS_S_FAILURE;
342c19800e8SDoug Rabson     }
343c19800e8SDoug Rabson 
344c19800e8SDoug Rabson     maj_stat = _gss_copy_buffer(minor_status, name_buffer, &name->value);
345c19800e8SDoug Rabson     if (maj_stat) {
346c19800e8SDoug Rabson 	gss_name_t rname = (gss_name_t)name;
347c19800e8SDoug Rabson 	_gss_spnego_release_name(minor_status, &rname);
348c19800e8SDoug Rabson 	return GSS_S_FAILURE;
349c19800e8SDoug Rabson     }
350c19800e8SDoug Rabson     name->mech = GSS_C_NO_NAME;
351c19800e8SDoug Rabson     *output_name = (gss_name_t)name;
352c19800e8SDoug Rabson 
353c19800e8SDoug Rabson     return GSS_S_COMPLETE;
354c19800e8SDoug Rabson }
355c19800e8SDoug Rabson 
356c19800e8SDoug Rabson OM_uint32 _gss_spnego_export_name
357c19800e8SDoug Rabson            (OM_uint32  * minor_status,
358c19800e8SDoug Rabson             const gss_name_t input_name,
359c19800e8SDoug Rabson             gss_buffer_t exported_name
360c19800e8SDoug Rabson            )
361c19800e8SDoug Rabson {
362c19800e8SDoug Rabson     spnego_name name;
363c19800e8SDoug Rabson     *minor_status = 0;
364c19800e8SDoug Rabson 
365c19800e8SDoug Rabson     if (input_name == GSS_C_NO_NAME)
366c19800e8SDoug Rabson 	return GSS_S_BAD_NAME;
367c19800e8SDoug Rabson 
368c19800e8SDoug Rabson     name = (spnego_name)input_name;
369c19800e8SDoug Rabson     if (name->mech == GSS_C_NO_NAME)
370c19800e8SDoug Rabson 	return GSS_S_BAD_NAME;
371c19800e8SDoug Rabson 
372c19800e8SDoug Rabson     return gss_export_name(minor_status, name->mech, exported_name);
373c19800e8SDoug Rabson }
374c19800e8SDoug Rabson 
375c19800e8SDoug Rabson OM_uint32 _gss_spnego_release_name
376c19800e8SDoug Rabson            (OM_uint32 * minor_status,
377c19800e8SDoug Rabson             gss_name_t * input_name
378c19800e8SDoug Rabson            )
379c19800e8SDoug Rabson {
380c19800e8SDoug Rabson     *minor_status = 0;
381c19800e8SDoug Rabson 
382c19800e8SDoug Rabson     if (*input_name != GSS_C_NO_NAME) {
383c19800e8SDoug Rabson 	OM_uint32 junk;
384c19800e8SDoug Rabson 	spnego_name name = (spnego_name)*input_name;
385c19800e8SDoug Rabson 	_gss_free_oid(&junk, &name->type);
386c19800e8SDoug Rabson 	gss_release_buffer(&junk, &name->value);
387c19800e8SDoug Rabson 	if (name->mech != GSS_C_NO_NAME)
388c19800e8SDoug Rabson 	    gss_release_name(&junk, &name->mech);
389c19800e8SDoug Rabson 	free(name);
390c19800e8SDoug Rabson 
391c19800e8SDoug Rabson 	*input_name = GSS_C_NO_NAME;
392c19800e8SDoug Rabson     }
393c19800e8SDoug Rabson     return GSS_S_COMPLETE;
394c19800e8SDoug Rabson }
395c19800e8SDoug Rabson 
396c19800e8SDoug Rabson OM_uint32 _gss_spnego_inquire_context (
397c19800e8SDoug Rabson             OM_uint32 * minor_status,
398c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
399c19800e8SDoug Rabson             gss_name_t * src_name,
400c19800e8SDoug Rabson             gss_name_t * targ_name,
401c19800e8SDoug Rabson             OM_uint32 * lifetime_rec,
402c19800e8SDoug Rabson             gss_OID * mech_type,
403c19800e8SDoug Rabson             OM_uint32 * ctx_flags,
404c19800e8SDoug Rabson             int * locally_initiated,
405c19800e8SDoug Rabson             int * open_context
406c19800e8SDoug Rabson            )
407c19800e8SDoug Rabson {
408c19800e8SDoug Rabson     gssspnego_ctx ctx;
409c19800e8SDoug Rabson 
410c19800e8SDoug Rabson     *minor_status = 0;
411c19800e8SDoug Rabson 
412c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
413c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
414c19800e8SDoug Rabson     }
415c19800e8SDoug Rabson 
416c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
417c19800e8SDoug Rabson 
418c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
419c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
420c19800e8SDoug Rabson     }
421c19800e8SDoug Rabson 
422c19800e8SDoug Rabson     return gss_inquire_context(minor_status,
423c19800e8SDoug Rabson 			       ctx->negotiated_ctx_id,
424c19800e8SDoug Rabson 			       src_name,
425c19800e8SDoug Rabson 			       targ_name,
426c19800e8SDoug Rabson 			       lifetime_rec,
427c19800e8SDoug Rabson 			       mech_type,
428c19800e8SDoug Rabson 			       ctx_flags,
429c19800e8SDoug Rabson 			       locally_initiated,
430c19800e8SDoug Rabson 			       open_context);
431c19800e8SDoug Rabson }
432c19800e8SDoug Rabson 
433c19800e8SDoug Rabson OM_uint32 _gss_spnego_wrap_size_limit (
434c19800e8SDoug Rabson             OM_uint32 * minor_status,
435c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
436c19800e8SDoug Rabson             int conf_req_flag,
437c19800e8SDoug Rabson             gss_qop_t qop_req,
438c19800e8SDoug Rabson             OM_uint32 req_output_size,
439c19800e8SDoug Rabson             OM_uint32 * max_input_size
440c19800e8SDoug Rabson            )
441c19800e8SDoug Rabson {
442c19800e8SDoug Rabson     gssspnego_ctx ctx;
443c19800e8SDoug Rabson 
444c19800e8SDoug Rabson     *minor_status = 0;
445c19800e8SDoug Rabson 
446c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
447c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
448c19800e8SDoug Rabson     }
449c19800e8SDoug Rabson 
450c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
451c19800e8SDoug Rabson 
452c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
453c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
454c19800e8SDoug Rabson     }
455c19800e8SDoug Rabson 
456c19800e8SDoug Rabson     return gss_wrap_size_limit(minor_status,
457c19800e8SDoug Rabson 			       ctx->negotiated_ctx_id,
458c19800e8SDoug Rabson 			       conf_req_flag,
459c19800e8SDoug Rabson 			       qop_req,
460c19800e8SDoug Rabson 			       req_output_size,
461c19800e8SDoug Rabson 			       max_input_size);
462c19800e8SDoug Rabson }
463c19800e8SDoug Rabson 
464c19800e8SDoug Rabson OM_uint32 _gss_spnego_export_sec_context (
465c19800e8SDoug Rabson             OM_uint32 * minor_status,
466c19800e8SDoug Rabson             gss_ctx_id_t * context_handle,
467c19800e8SDoug Rabson             gss_buffer_t interprocess_token
468c19800e8SDoug Rabson            )
469c19800e8SDoug Rabson {
470c19800e8SDoug Rabson     gssspnego_ctx ctx;
471c19800e8SDoug Rabson     OM_uint32 ret;
472c19800e8SDoug Rabson 
473c19800e8SDoug Rabson     *minor_status = 0;
474c19800e8SDoug Rabson 
475c19800e8SDoug Rabson     if (context_handle == NULL) {
476c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
477c19800e8SDoug Rabson     }
478c19800e8SDoug Rabson 
479c19800e8SDoug Rabson     ctx = (gssspnego_ctx)*context_handle;
480c19800e8SDoug Rabson 
481c19800e8SDoug Rabson     if (ctx == NULL)
482c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
483c19800e8SDoug Rabson 
484c19800e8SDoug Rabson     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
485c19800e8SDoug Rabson 
486c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
487c19800e8SDoug Rabson 	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
488c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
489c19800e8SDoug Rabson     }
490c19800e8SDoug Rabson 
491c19800e8SDoug Rabson     ret = gss_export_sec_context(minor_status,
492c19800e8SDoug Rabson 				 &ctx->negotiated_ctx_id,
493c19800e8SDoug Rabson 				 interprocess_token);
494c19800e8SDoug Rabson     if (ret == GSS_S_COMPLETE) {
495c19800e8SDoug Rabson 	ret = _gss_spnego_internal_delete_sec_context(minor_status,
496c19800e8SDoug Rabson 					     context_handle,
497c19800e8SDoug Rabson 					     GSS_C_NO_BUFFER);
498c19800e8SDoug Rabson 	if (ret == GSS_S_COMPLETE)
499c19800e8SDoug Rabson 	    return GSS_S_COMPLETE;
500c19800e8SDoug Rabson     }
501c19800e8SDoug Rabson 
502c19800e8SDoug Rabson     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
503c19800e8SDoug Rabson 
504c19800e8SDoug Rabson     return ret;
505c19800e8SDoug Rabson }
506c19800e8SDoug Rabson 
507c19800e8SDoug Rabson OM_uint32 _gss_spnego_import_sec_context (
508c19800e8SDoug Rabson             OM_uint32 * minor_status,
509c19800e8SDoug Rabson             const gss_buffer_t interprocess_token,
510c19800e8SDoug Rabson             gss_ctx_id_t *context_handle
511c19800e8SDoug Rabson            )
512c19800e8SDoug Rabson {
513c19800e8SDoug Rabson     OM_uint32 ret, minor;
514c19800e8SDoug Rabson     gss_ctx_id_t context;
515c19800e8SDoug Rabson     gssspnego_ctx ctx;
516c19800e8SDoug Rabson 
517c19800e8SDoug Rabson     ret = _gss_spnego_alloc_sec_context(minor_status, &context);
518c19800e8SDoug Rabson     if (ret != GSS_S_COMPLETE) {
519c19800e8SDoug Rabson 	return ret;
520c19800e8SDoug Rabson     }
521c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context;
522c19800e8SDoug Rabson 
523c19800e8SDoug Rabson     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
524c19800e8SDoug Rabson 
525c19800e8SDoug Rabson     ret = gss_import_sec_context(minor_status,
526c19800e8SDoug Rabson 				 interprocess_token,
527c19800e8SDoug Rabson 				 &ctx->negotiated_ctx_id);
528c19800e8SDoug Rabson     if (ret != GSS_S_COMPLETE) {
529c19800e8SDoug Rabson 	_gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER);
530c19800e8SDoug Rabson 	return ret;
531c19800e8SDoug Rabson     }
532c19800e8SDoug Rabson 
533c19800e8SDoug Rabson     ctx->open = 1;
534c19800e8SDoug Rabson     /* don't bother filling in the rest of the fields */
535c19800e8SDoug Rabson 
536c19800e8SDoug Rabson     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
537c19800e8SDoug Rabson 
538c19800e8SDoug Rabson     *context_handle = (gss_ctx_id_t)ctx;
539c19800e8SDoug Rabson 
540c19800e8SDoug Rabson     return GSS_S_COMPLETE;
541c19800e8SDoug Rabson }
542c19800e8SDoug Rabson 
543c19800e8SDoug Rabson OM_uint32 _gss_spnego_inquire_names_for_mech (
544c19800e8SDoug Rabson             OM_uint32 * minor_status,
545c19800e8SDoug Rabson             const gss_OID mechanism,
546c19800e8SDoug Rabson             gss_OID_set * name_types
547c19800e8SDoug Rabson            )
548c19800e8SDoug Rabson {
549c19800e8SDoug Rabson     gss_OID_set mechs, names, n;
550c19800e8SDoug Rabson     OM_uint32 ret, junk;
551c19800e8SDoug Rabson     int i, j;
552c19800e8SDoug Rabson 
553c19800e8SDoug Rabson     *name_types = NULL;
554c19800e8SDoug Rabson 
555c19800e8SDoug Rabson     ret = spnego_supported_mechs(minor_status, &mechs);
556c19800e8SDoug Rabson     if (ret != GSS_S_COMPLETE)
557c19800e8SDoug Rabson 	return ret;
558c19800e8SDoug Rabson 
559c19800e8SDoug Rabson     ret = gss_create_empty_oid_set(minor_status, &names);
560c19800e8SDoug Rabson     if (ret != GSS_S_COMPLETE)
561c19800e8SDoug Rabson 	goto out;
562c19800e8SDoug Rabson 
563c19800e8SDoug Rabson     for (i = 0; i < mechs->count; i++) {
564c19800e8SDoug Rabson 	ret = gss_inquire_names_for_mech(minor_status,
565c19800e8SDoug Rabson 					 &mechs->elements[i],
566c19800e8SDoug Rabson 					 &n);
567c19800e8SDoug Rabson 	if (ret)
568c19800e8SDoug Rabson 	    continue;
569c19800e8SDoug Rabson 
570c19800e8SDoug Rabson 	for (j = 0; j < n->count; j++)
571c19800e8SDoug Rabson 	    gss_add_oid_set_member(minor_status,
572c19800e8SDoug Rabson 				   &n->elements[j],
573c19800e8SDoug Rabson 				   &names);
574c19800e8SDoug Rabson 	gss_release_oid_set(&junk, &n);
575c19800e8SDoug Rabson     }
576c19800e8SDoug Rabson 
577c19800e8SDoug Rabson     ret = GSS_S_COMPLETE;
578c19800e8SDoug Rabson     *name_types = names;
579c19800e8SDoug Rabson out:
580c19800e8SDoug Rabson 
581c19800e8SDoug Rabson     gss_release_oid_set(&junk, &mechs);
582c19800e8SDoug Rabson 
583c19800e8SDoug Rabson     return GSS_S_COMPLETE;
584c19800e8SDoug Rabson }
585c19800e8SDoug Rabson 
586c19800e8SDoug Rabson OM_uint32 _gss_spnego_inquire_mechs_for_name (
587c19800e8SDoug Rabson             OM_uint32 * minor_status,
588c19800e8SDoug Rabson             const gss_name_t input_name,
589c19800e8SDoug Rabson             gss_OID_set * mech_types
590c19800e8SDoug Rabson            )
591c19800e8SDoug Rabson {
592c19800e8SDoug Rabson     OM_uint32 ret, junk;
593c19800e8SDoug Rabson 
594c19800e8SDoug Rabson     ret = gss_create_empty_oid_set(minor_status, mech_types);
595c19800e8SDoug Rabson     if (ret)
596c19800e8SDoug Rabson 	return ret;
597c19800e8SDoug Rabson 
598c19800e8SDoug Rabson     ret = gss_add_oid_set_member(minor_status,
599c19800e8SDoug Rabson 				 GSS_SPNEGO_MECHANISM,
600c19800e8SDoug Rabson 				 mech_types);
601c19800e8SDoug Rabson     if (ret)
602c19800e8SDoug Rabson 	gss_release_oid_set(&junk, mech_types);
603c19800e8SDoug Rabson 
604c19800e8SDoug Rabson     return ret;
605c19800e8SDoug Rabson }
606c19800e8SDoug Rabson 
607c19800e8SDoug Rabson OM_uint32 _gss_spnego_canonicalize_name (
608c19800e8SDoug Rabson             OM_uint32 * minor_status,
609c19800e8SDoug Rabson             const gss_name_t input_name,
610c19800e8SDoug Rabson             const gss_OID mech_type,
611c19800e8SDoug Rabson             gss_name_t * output_name
612c19800e8SDoug Rabson            )
613c19800e8SDoug Rabson {
614c19800e8SDoug Rabson     /* XXX */
615c19800e8SDoug Rabson     return gss_duplicate_name(minor_status, input_name, output_name);
616c19800e8SDoug Rabson }
617c19800e8SDoug Rabson 
618c19800e8SDoug Rabson OM_uint32 _gss_spnego_duplicate_name (
619c19800e8SDoug Rabson             OM_uint32 * minor_status,
620c19800e8SDoug Rabson             const gss_name_t src_name,
621c19800e8SDoug Rabson             gss_name_t * dest_name
622c19800e8SDoug Rabson            )
623c19800e8SDoug Rabson {
624c19800e8SDoug Rabson     return gss_duplicate_name(minor_status, src_name, dest_name);
625c19800e8SDoug Rabson }
626c19800e8SDoug Rabson 
627c19800e8SDoug Rabson OM_uint32 _gss_spnego_sign
628c19800e8SDoug Rabson            (OM_uint32 * minor_status,
629c19800e8SDoug Rabson             gss_ctx_id_t context_handle,
630c19800e8SDoug Rabson             int qop_req,
631c19800e8SDoug Rabson             gss_buffer_t message_buffer,
632c19800e8SDoug Rabson             gss_buffer_t message_token
633c19800e8SDoug Rabson            )
634c19800e8SDoug Rabson {
635c19800e8SDoug Rabson     gssspnego_ctx ctx;
636c19800e8SDoug Rabson 
637c19800e8SDoug Rabson     *minor_status = 0;
638c19800e8SDoug Rabson 
639c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
640c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
641c19800e8SDoug Rabson     }
642c19800e8SDoug Rabson 
643c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
644c19800e8SDoug Rabson 
645c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
646c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
647c19800e8SDoug Rabson     }
648c19800e8SDoug Rabson 
649c19800e8SDoug Rabson     return gss_sign(minor_status,
650c19800e8SDoug Rabson 		    ctx->negotiated_ctx_id,
651c19800e8SDoug Rabson 		    qop_req,
652c19800e8SDoug Rabson 		    message_buffer,
653c19800e8SDoug Rabson 		    message_token);
654c19800e8SDoug Rabson }
655c19800e8SDoug Rabson 
656c19800e8SDoug Rabson OM_uint32 _gss_spnego_verify
657c19800e8SDoug Rabson            (OM_uint32 * minor_status,
658c19800e8SDoug Rabson             gss_ctx_id_t context_handle,
659c19800e8SDoug Rabson             gss_buffer_t message_buffer,
660c19800e8SDoug Rabson             gss_buffer_t token_buffer,
661c19800e8SDoug Rabson             int * qop_state
662c19800e8SDoug Rabson            )
663c19800e8SDoug Rabson {
664c19800e8SDoug Rabson     gssspnego_ctx ctx;
665c19800e8SDoug Rabson 
666c19800e8SDoug Rabson     *minor_status = 0;
667c19800e8SDoug Rabson 
668c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
669c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
670c19800e8SDoug Rabson     }
671c19800e8SDoug Rabson 
672c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
673c19800e8SDoug Rabson 
674c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
675c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
676c19800e8SDoug Rabson     }
677c19800e8SDoug Rabson 
678c19800e8SDoug Rabson     return gss_verify(minor_status,
679c19800e8SDoug Rabson 		      ctx->negotiated_ctx_id,
680c19800e8SDoug Rabson 		      message_buffer,
681c19800e8SDoug Rabson 		      token_buffer,
682c19800e8SDoug Rabson 		      qop_state);
683c19800e8SDoug Rabson }
684c19800e8SDoug Rabson 
685c19800e8SDoug Rabson OM_uint32 _gss_spnego_seal
686c19800e8SDoug Rabson            (OM_uint32 * minor_status,
687c19800e8SDoug Rabson             gss_ctx_id_t context_handle,
688c19800e8SDoug Rabson             int conf_req_flag,
689c19800e8SDoug Rabson             int qop_req,
690c19800e8SDoug Rabson             gss_buffer_t input_message_buffer,
691c19800e8SDoug Rabson             int * conf_state,
692c19800e8SDoug Rabson             gss_buffer_t output_message_buffer
693c19800e8SDoug Rabson            )
694c19800e8SDoug Rabson {
695c19800e8SDoug Rabson     gssspnego_ctx ctx;
696c19800e8SDoug Rabson 
697c19800e8SDoug Rabson     *minor_status = 0;
698c19800e8SDoug Rabson 
699c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
700c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
701c19800e8SDoug Rabson     }
702c19800e8SDoug Rabson 
703c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
704c19800e8SDoug Rabson 
705c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
706c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
707c19800e8SDoug Rabson     }
708c19800e8SDoug Rabson 
709c19800e8SDoug Rabson     return gss_seal(minor_status,
710c19800e8SDoug Rabson 		    ctx->negotiated_ctx_id,
711c19800e8SDoug Rabson 		    conf_req_flag,
712c19800e8SDoug Rabson 		    qop_req,
713c19800e8SDoug Rabson 		    input_message_buffer,
714c19800e8SDoug Rabson 		    conf_state,
715c19800e8SDoug Rabson 		    output_message_buffer);
716c19800e8SDoug Rabson }
717c19800e8SDoug Rabson 
718c19800e8SDoug Rabson OM_uint32 _gss_spnego_unseal
719c19800e8SDoug Rabson            (OM_uint32 * minor_status,
720c19800e8SDoug Rabson             gss_ctx_id_t context_handle,
721c19800e8SDoug Rabson             gss_buffer_t input_message_buffer,
722c19800e8SDoug Rabson             gss_buffer_t output_message_buffer,
723c19800e8SDoug Rabson             int * conf_state,
724c19800e8SDoug Rabson             int * qop_state
725c19800e8SDoug Rabson            )
726c19800e8SDoug Rabson {
727c19800e8SDoug Rabson     gssspnego_ctx ctx;
728c19800e8SDoug Rabson 
729c19800e8SDoug Rabson     *minor_status = 0;
730c19800e8SDoug Rabson 
731c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
732c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
733c19800e8SDoug Rabson     }
734c19800e8SDoug Rabson 
735c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
736c19800e8SDoug Rabson 
737c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
738c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
739c19800e8SDoug Rabson     }
740c19800e8SDoug Rabson 
741c19800e8SDoug Rabson     return gss_unseal(minor_status,
742c19800e8SDoug Rabson 		      ctx->negotiated_ctx_id,
743c19800e8SDoug Rabson 		      input_message_buffer,
744c19800e8SDoug Rabson 		      output_message_buffer,
745c19800e8SDoug Rabson 		      conf_state,
746c19800e8SDoug Rabson 		      qop_state);
747c19800e8SDoug Rabson }
748c19800e8SDoug Rabson 
749c19800e8SDoug Rabson #if 0
750c19800e8SDoug Rabson OM_uint32 _gss_spnego_unwrap_ex
751c19800e8SDoug Rabson            (OM_uint32 * minor_status,
752c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
753c19800e8SDoug Rabson 	    const gss_buffer_t token_header_buffer,
754c19800e8SDoug Rabson 	    const gss_buffer_t associated_data_buffer,
755c19800e8SDoug Rabson 	    const gss_buffer_t input_message_buffer,
756c19800e8SDoug Rabson 	    gss_buffer_t output_message_buffer,
757c19800e8SDoug Rabson 	    int * conf_state,
758c19800e8SDoug Rabson 	    gss_qop_t * qop_state)
759c19800e8SDoug Rabson {
760c19800e8SDoug Rabson     gssspnego_ctx ctx;
761c19800e8SDoug Rabson 
762c19800e8SDoug Rabson     *minor_status = 0;
763c19800e8SDoug Rabson 
764c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
765c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
766c19800e8SDoug Rabson     }
767c19800e8SDoug Rabson 
768c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
769c19800e8SDoug Rabson 
770c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
771c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
772c19800e8SDoug Rabson     }
773c19800e8SDoug Rabson 
774c19800e8SDoug Rabson     return gss_unwrap_ex(minor_status,
775c19800e8SDoug Rabson 			 ctx->negotiated_ctx_id,
776c19800e8SDoug Rabson 			 token_header_buffer,
777c19800e8SDoug Rabson 			 associated_data_buffer,
778c19800e8SDoug Rabson 			 input_message_buffer,
779c19800e8SDoug Rabson 			 output_message_buffer,
780c19800e8SDoug Rabson 			 conf_state,
781c19800e8SDoug Rabson 			 qop_state);
782c19800e8SDoug Rabson }
783c19800e8SDoug Rabson 
784c19800e8SDoug Rabson OM_uint32 _gss_spnego_wrap_ex
785c19800e8SDoug Rabson            (OM_uint32 * minor_status,
786c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
787c19800e8SDoug Rabson             int conf_req_flag,
788c19800e8SDoug Rabson             gss_qop_t qop_req,
789c19800e8SDoug Rabson             const gss_buffer_t associated_data_buffer,
790c19800e8SDoug Rabson             const gss_buffer_t input_message_buffer,
791c19800e8SDoug Rabson             int * conf_state,
792c19800e8SDoug Rabson             gss_buffer_t output_token_buffer,
793c19800e8SDoug Rabson             gss_buffer_t output_message_buffer
794c19800e8SDoug Rabson 	   )
795c19800e8SDoug Rabson {
796c19800e8SDoug Rabson     gssspnego_ctx ctx;
797c19800e8SDoug Rabson 
798c19800e8SDoug Rabson     *minor_status = 0;
799c19800e8SDoug Rabson 
800c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
801c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
802c19800e8SDoug Rabson     }
803c19800e8SDoug Rabson 
804c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
805c19800e8SDoug Rabson 
806c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
807c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
808c19800e8SDoug Rabson     }
809c19800e8SDoug Rabson 
810c19800e8SDoug Rabson     if ((ctx->mech_flags & GSS_C_DCE_STYLE) == 0 &&
811c19800e8SDoug Rabson 	associated_data_buffer->length != input_message_buffer->length) {
812c19800e8SDoug Rabson 	*minor_status = EINVAL;
813c19800e8SDoug Rabson 	return GSS_S_BAD_QOP;
814c19800e8SDoug Rabson     }
815c19800e8SDoug Rabson 
816c19800e8SDoug Rabson     return gss_wrap_ex(minor_status,
817c19800e8SDoug Rabson 		       ctx->negotiated_ctx_id,
818c19800e8SDoug Rabson 		       conf_req_flag,
819c19800e8SDoug Rabson 		       qop_req,
820c19800e8SDoug Rabson 		       associated_data_buffer,
821c19800e8SDoug Rabson 		       input_message_buffer,
822c19800e8SDoug Rabson 		       conf_state,
823c19800e8SDoug Rabson 		       output_token_buffer,
824c19800e8SDoug Rabson 		       output_message_buffer);
825c19800e8SDoug Rabson }
826c19800e8SDoug Rabson 
827c19800e8SDoug Rabson OM_uint32 _gss_spnego_complete_auth_token
828c19800e8SDoug Rabson            (OM_uint32 * minor_status,
829c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
830c19800e8SDoug Rabson 	    gss_buffer_t input_message_buffer)
831c19800e8SDoug Rabson {
832c19800e8SDoug Rabson     gssspnego_ctx ctx;
833c19800e8SDoug Rabson 
834c19800e8SDoug Rabson     *minor_status = 0;
835c19800e8SDoug Rabson 
836c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
837c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
838c19800e8SDoug Rabson     }
839c19800e8SDoug Rabson 
840c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
841c19800e8SDoug Rabson 
842c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
843c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
844c19800e8SDoug Rabson     }
845c19800e8SDoug Rabson 
846c19800e8SDoug Rabson     return gss_complete_auth_token(minor_status,
847c19800e8SDoug Rabson 				   ctx->negotiated_ctx_id,
848c19800e8SDoug Rabson 				   input_message_buffer);
849c19800e8SDoug Rabson }
850c19800e8SDoug Rabson #endif
851c19800e8SDoug Rabson 
852c19800e8SDoug Rabson OM_uint32 _gss_spnego_inquire_sec_context_by_oid
853c19800e8SDoug Rabson            (OM_uint32 * minor_status,
854c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
855c19800e8SDoug Rabson             const gss_OID desired_object,
856c19800e8SDoug Rabson             gss_buffer_set_t *data_set)
857c19800e8SDoug Rabson {
858c19800e8SDoug Rabson     gssspnego_ctx ctx;
859c19800e8SDoug Rabson 
860c19800e8SDoug Rabson     *minor_status = 0;
861c19800e8SDoug Rabson 
862c19800e8SDoug Rabson     if (context_handle == GSS_C_NO_CONTEXT) {
863c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
864c19800e8SDoug Rabson     }
865c19800e8SDoug Rabson 
866c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
867c19800e8SDoug Rabson 
868c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
869c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
870c19800e8SDoug Rabson     }
871c19800e8SDoug Rabson 
872c19800e8SDoug Rabson     return gss_inquire_sec_context_by_oid(minor_status,
873c19800e8SDoug Rabson 					  ctx->negotiated_ctx_id,
874c19800e8SDoug Rabson 					  desired_object,
875c19800e8SDoug Rabson 					  data_set);
876c19800e8SDoug Rabson }
877c19800e8SDoug Rabson 
878c19800e8SDoug Rabson OM_uint32 _gss_spnego_set_sec_context_option
879c19800e8SDoug Rabson            (OM_uint32 * minor_status,
880c19800e8SDoug Rabson             gss_ctx_id_t * context_handle,
881c19800e8SDoug Rabson             const gss_OID desired_object,
882c19800e8SDoug Rabson             const gss_buffer_t value)
883c19800e8SDoug Rabson {
884c19800e8SDoug Rabson     gssspnego_ctx ctx;
885c19800e8SDoug Rabson 
886c19800e8SDoug Rabson     *minor_status = 0;
887c19800e8SDoug Rabson 
888c19800e8SDoug Rabson     if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) {
889c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
890c19800e8SDoug Rabson     }
891c19800e8SDoug Rabson 
892c19800e8SDoug Rabson     ctx = (gssspnego_ctx)context_handle;
893c19800e8SDoug Rabson 
894c19800e8SDoug Rabson     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
895c19800e8SDoug Rabson 	return GSS_S_NO_CONTEXT;
896c19800e8SDoug Rabson     }
897c19800e8SDoug Rabson 
898c19800e8SDoug Rabson     return gss_set_sec_context_option(minor_status,
899c19800e8SDoug Rabson 				      &ctx->negotiated_ctx_id,
900c19800e8SDoug Rabson 				      desired_object,
901c19800e8SDoug Rabson 				      value);
902c19800e8SDoug Rabson }
903c19800e8SDoug Rabson 
904