Initial import from FreeBSD RELENG_4:
[games.git] / crypto / heimdal / lib / gssapi / export_sec_context.c
1 /*
2  * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden). 
4  * All rights reserved. 
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met: 
9  *
10  * 1. Redistributions of source code must retain the above copyright 
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright 
14  *    notice, this list of conditions and the following disclaimer in the 
15  *    documentation and/or other materials provided with the distribution. 
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors 
18  *    may be used to endorse or promote products derived from this software 
19  *    without specific prior written permission. 
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
31  * SUCH DAMAGE. 
32  */
33
34 #include "gssapi_locl.h"
35
36 RCSID("$Id: export_sec_context.c,v 1.4 2001/02/18 03:39:09 assar Exp $");
37
38 OM_uint32
39 gss_export_sec_context (
40     OM_uint32 * minor_status,
41     gss_ctx_id_t * context_handle,
42     gss_buffer_t interprocess_token
43     )
44 {
45     krb5_storage *sp;
46     krb5_auth_context ac;
47     OM_uint32 ret = GSS_S_COMPLETE;
48     krb5_data data;
49     gss_buffer_desc buffer;
50     int flags;
51     OM_uint32 minor;
52     krb5_error_code kret;
53
54     gssapi_krb5_init ();
55     if (!((*context_handle)->flags & GSS_C_TRANS_FLAG))
56         return GSS_S_UNAVAILABLE;
57
58     sp = krb5_storage_emem ();
59     if (sp == NULL) {
60         *minor_status = ENOMEM;
61         return GSS_S_FAILURE;
62     }
63     ac = (*context_handle)->auth_context;
64
65     /* flagging included fields */
66
67     flags = 0;
68     if (ac->local_address)
69         flags |= SC_LOCAL_ADDRESS;
70     if (ac->remote_address)
71         flags |= SC_REMOTE_ADDRESS;
72     if (ac->keyblock)
73         flags |= SC_KEYBLOCK;
74     if (ac->local_subkey)
75         flags |= SC_LOCAL_SUBKEY;
76     if (ac->remote_subkey)
77         flags |= SC_REMOTE_SUBKEY;
78
79     kret = krb5_store_int32 (sp, flags);
80     if (kret) {
81         *minor_status = kret;
82         goto failure;
83     }
84
85     /* marshall auth context */
86
87     kret = krb5_store_int32 (sp, ac->flags);
88     if (kret) {
89         *minor_status = kret;
90         goto failure;
91     }
92     if (ac->local_address) {
93         kret = krb5_store_address (sp, *ac->local_address);
94         if (kret) {
95             *minor_status = kret;
96             goto failure;
97         }
98     }
99     if (ac->remote_address) {
100         kret = krb5_store_address (sp, *ac->remote_address);
101         if (kret) {
102             *minor_status = kret;
103             goto failure;
104         }
105     }
106     kret = krb5_store_int16 (sp, ac->local_port);
107     if (kret) {
108         *minor_status = kret;
109         goto failure;
110     }
111     kret = krb5_store_int16 (sp, ac->remote_port);
112     if (kret) {
113         *minor_status = kret;
114         goto failure;
115     }
116     if (ac->keyblock) {
117         kret = krb5_store_keyblock (sp, *ac->keyblock);
118         if (kret) {
119             *minor_status = kret;
120             goto failure;
121         }
122     }
123     if (ac->local_subkey) {
124         kret = krb5_store_keyblock (sp, *ac->local_subkey);
125         if (kret) {
126             *minor_status = kret;
127             goto failure;
128         }
129     }
130     if (ac->remote_subkey) {
131         kret = krb5_store_keyblock (sp, *ac->remote_subkey);
132         if (kret) {
133             *minor_status = kret;
134             goto failure;
135         }
136     }
137     kret = krb5_store_int32 (sp, ac->local_seqnumber);
138         if (kret) {
139             *minor_status = kret;
140             goto failure;
141         }
142     kret = krb5_store_int32 (sp, ac->remote_seqnumber);
143         if (kret) {
144             *minor_status = kret;
145             goto failure;
146         }
147
148 #if 0
149     {
150         size_t sz;
151         unsigned char auth_buf[1024];
152
153         ret = encode_Authenticator (auth_buf, sizeof(auth_buf),
154                                     ac->authenticator, &sz);
155         if (ret) {
156             krb5_storage_free (sp);
157             *minor_status = ret;
158             return GSS_S_FAILURE;
159         }
160         data.data   = auth_buf;
161         data.length = sz;
162         kret = krb5_store_data (sp, data);
163         if (kret) {
164             *minor_status = kret;
165             goto failure;
166         }
167     }
168 #endif
169     kret = krb5_store_int32 (sp, ac->keytype);
170     if (kret) {
171         *minor_status = kret;
172         goto failure;
173     }
174     kret = krb5_store_int32 (sp, ac->cksumtype);
175     if (kret) {
176         *minor_status = kret;
177         goto failure;
178     }
179
180     /* names */
181
182     ret = gss_export_name (minor_status, (*context_handle)->source, &buffer);
183     if (ret)
184         goto failure;
185     data.data   = buffer.value;
186     data.length = buffer.length;
187     kret = krb5_store_data (sp, data);
188     gss_release_buffer (&minor, &buffer);
189     if (kret) {
190         *minor_status = kret;
191         goto failure;
192     }
193
194     ret = gss_export_name (minor_status, (*context_handle)->target, &buffer);
195     if (ret)
196         goto failure;
197     data.data   = buffer.value;
198     data.length = buffer.length;
199     kret = krb5_store_data (sp, data);
200     gss_release_buffer (&minor, &buffer);
201     if (kret) {
202         *minor_status = kret;
203         goto failure;
204     }
205
206     kret = krb5_store_int32 (sp, (*context_handle)->flags);
207     if (kret) {
208         *minor_status = kret;
209         goto failure;
210     }
211     kret = krb5_store_int32 (sp, (*context_handle)->more_flags);
212     if (kret) {
213         *minor_status = kret;
214         goto failure;
215     }
216
217     kret = krb5_storage_to_data (sp, &data);
218     krb5_storage_free (sp);
219     if (kret) {
220         *minor_status = kret;
221         return GSS_S_FAILURE;
222     }
223     interprocess_token->length = data.length;
224     interprocess_token->value  = data.data;
225     ret = gss_delete_sec_context (minor_status, context_handle,
226                                   GSS_C_NO_BUFFER);
227     if (ret != GSS_S_COMPLETE)
228         gss_release_buffer (NULL, interprocess_token);
229     return ret;
230  failure:
231     krb5_storage_free (sp);
232     return ret;
233 }