2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
5 /* -*- mode: c; indent-tabs-mode: nil -*- */
7 * lib/gssapi/krb5/lucid_context.c
9 * Copyright 2004, 2008 by the Massachusetts Institute of Technology.
10 * All Rights Reserved.
12 * Export of this software from the United States of America may
13 * require a specific license from the United States Government.
14 * It is the responsibility of any person or organization contemplating
15 * export to obtain such a license before exporting.
17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18 * distribute this software and its documentation for any purpose and
19 * without fee is hereby granted, provided that the above copyright
20 * notice appear in all copies and that both that copyright notice and
21 * this permission notice appear in supporting documentation, and that
22 * the name of M.I.T. not be used in advertising or publicity pertaining
23 * to distribution of the software without specific, written prior
24 * permission. Furthermore if you modify this software you must label
25 * your software as modified software and not distribute it in such a
26 * fashion that it might be confused with the original M.I.T. software.
27 * M.I.T. makes no representations about the suitability of
28 * this software for any purpose. It is provided "as is" without express
29 * or implied warranty.
34 * lucid_context.c - Externalize a "lucid" security
35 * context from a krb5_gss_ctx_id_rec structure.
37 #include "gssapiP_krb5.h"
38 #include "gssapi_krb5.h"
39 #include "mechglueP.h" /* SUNW17PACresync */
42 * Local routine prototypes
45 free_external_lucid_ctx_v1(
46 gss_krb5_lucid_context_v1_t
*ctx
);
50 gss_krb5_lucid_key_t
*key
);
52 static krb5_error_code
53 copy_keyblock_to_lucid_key(
55 gss_krb5_lucid_key_t
*lkey
);
57 static krb5_error_code
58 make_external_lucid_ctx_v1(
59 krb5_gss_ctx_id_rec
* gctx
,
68 OM_uint32 KRB5_CALLCONV
69 gss_krb5int_export_lucid_sec_context(
70 OM_uint32
*minor_status
,
71 gss_ctx_id_t context_handle
,
72 const gss_OID desired_object
,
73 gss_buffer_set_t
*data_set
)
75 krb5_error_code kret
= 0;
77 krb5_gss_ctx_id_t ctx
= (krb5_gss_ctx_id_t
)context_handle
;
83 retval
= GSS_S_FAILURE
;
85 *data_set
= GSS_C_NO_BUFFER_SET
;
87 retval
= generic_gss_oid_decompose(minor_status
,
88 GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID
,
89 GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH
,
92 if (GSS_ERROR(retval
))
95 /* Externalize a structure of the right version */
98 kret
= make_external_lucid_ctx_v1((krb5_pointer
)ctx
,
102 kret
= (OM_uint32
) KG_LUCID_VERSION
;
109 /* Success! Record the context and return the buffer */
110 if (! kg_save_lucidctx_id((void *)lctx
)) {
111 kret
= G_VALIDATE_FAILED
;
116 rep
.length
= sizeof(lctx
);
118 retval
= generic_gss_add_buffer_set_member(minor_status
, &rep
, data_set
);
119 if (GSS_ERROR(retval
))
123 if (*minor_status
== 0)
124 *minor_status
= (OM_uint32
) kret
;
129 * Frees the storage associated with an
130 * exported lucid context structure.
133 gss_krb5int_free_lucid_sec_context(
134 OM_uint32
*minor_status
,
135 const gss_OID desired_mech
,
136 const gss_OID desired_object
,
140 krb5_error_code kret
= 0;
145 retval
= GSS_S_FAILURE
;
154 /* Verify pointer is valid lucid context */
155 if (! kg_validate_lucidctx_id(kctx
)) {
156 kret
= G_VALIDATE_FAILED
;
160 /* Determine version and call correct free routine */
161 version
= ((gss_krb5_lucid_context_version_t
*)kctx
)->version
;
164 (void)kg_delete_lucidctx_id(kctx
);
165 free_external_lucid_ctx_v1((gss_krb5_lucid_context_v1_t
*) kctx
);
177 retval
= GSS_S_COMPLETE
;
182 if (*minor_status
== 0)
183 *minor_status
= (OM_uint32
) kret
;
191 static krb5_error_code
192 make_external_lucid_ctx_v1(
193 krb5_gss_ctx_id_rec
* gctx
,
197 gss_krb5_lucid_context_v1_t
*lctx
= NULL
;
198 unsigned int bufsize
= sizeof(gss_krb5_lucid_context_v1_t
);
199 krb5_error_code retval
;
201 /* Allocate the structure */
202 if ((lctx
= xmalloc(bufsize
)) == NULL
) {
207 memset(lctx
, 0, bufsize
);
210 lctx
->initiate
= gctx
->initiate
? 1 : 0;
211 lctx
->endtime
= gctx
->krb_times
.endtime
;
212 lctx
->send_seq
= gctx
->seq_send
;
213 lctx
->recv_seq
= gctx
->seq_recv
;
214 lctx
->protocol
= gctx
->proto
;
215 /* gctx->proto == 0 ==> rfc1964-style key information
216 gctx->proto == 1 ==> cfx-style (draft-ietf-krb-wg-gssapi-cfx-07) keys */
217 if (gctx
->proto
== 0) {
218 lctx
->rfc1964_kd
.sign_alg
= gctx
->signalg
;
219 lctx
->rfc1964_kd
.seal_alg
= gctx
->sealalg
;
221 if ((retval
= copy_keyblock_to_lucid_key(gctx
->seq
,
222 &lctx
->rfc1964_kd
.ctx_key
)))
225 else if (gctx
->proto
== 1) {
227 /* (subkey is always present, either a copy of the kerberos
228 session key or a subkey) */
229 if ((retval
= copy_keyblock_to_lucid_key(gctx
->subkey
,
230 &lctx
->cfx_kd
.ctx_key
)))
232 if (gctx
->have_acceptor_subkey
) {
233 if ((retval
= copy_keyblock_to_lucid_key(gctx
->acceptor_subkey
,
234 &lctx
->cfx_kd
.acceptor_subkey
)))
236 lctx
->cfx_kd
.have_acceptor_subkey
= 1;
240 return EINVAL
; /* XXX better error code? */
249 free_external_lucid_ctx_v1(lctx
);
255 /* Copy the contents of a krb5_keyblock to a gss_krb5_lucid_key_t structure */
256 static krb5_error_code
257 copy_keyblock_to_lucid_key(
258 krb5_keyblock
*k5key
,
259 gss_krb5_lucid_key_t
*lkey
)
261 if (!k5key
|| !k5key
->contents
|| k5key
->length
== 0)
264 memset(lkey
, 0, sizeof(gss_krb5_lucid_key_t
));
266 /* Allocate storage for the key data */
267 if ((lkey
->data
= xmalloc(k5key
->length
)) == NULL
) {
270 memcpy(lkey
->data
, k5key
->contents
, k5key
->length
);
271 lkey
->length
= k5key
->length
;
272 lkey
->type
= k5key
->enctype
;
278 /* Free any storage associated with a gss_krb5_lucid_key_t structure */
281 gss_krb5_lucid_key_t
*key
)
284 if (key
->data
&& key
->length
) {
285 memset(key
->data
, 0, key
->length
);
287 memset(key
, 0, sizeof(gss_krb5_lucid_key_t
));
291 /* Free any storage associated with a gss_krb5_lucid_context_v1 structure */
293 free_external_lucid_ctx_v1(
294 gss_krb5_lucid_context_v1_t
*ctx
)
297 if (ctx
->protocol
== 0) {
298 free_lucid_key_data(&ctx
->rfc1964_kd
.ctx_key
);
300 if (ctx
->protocol
== 1) {
301 free_lucid_key_data(&ctx
->cfx_kd
.ctx_key
);
302 if (ctx
->cfx_kd
.have_acceptor_subkey
)
303 free_lucid_key_data(&ctx
->cfx_kd
.acceptor_subkey
);