1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/gssapi/krb5/lucid_context.c */
4 * Copyright 2004, 2008 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
27 /* Externalize a "lucid" security context from a krb5_gss_ctx_id_rec
29 #include "gssapiP_krb5.h"
30 #include "gssapi_krb5.h"
33 * Local routine prototypes
36 free_external_lucid_ctx_v1(
37 gss_krb5_lucid_context_v1_t *ctx);
41 gss_krb5_lucid_key_t *key);
43 static krb5_error_code
44 copy_keyblock_to_lucid_key(
46 gss_krb5_lucid_key_t *lkey);
48 static krb5_error_code
49 make_external_lucid_ctx_v1(
50 krb5_gss_ctx_id_rec * gctx,
60 gss_krb5int_export_lucid_sec_context(
61 OM_uint32 *minor_status,
62 const gss_ctx_id_t context_handle,
63 const gss_OID desired_object,
64 gss_buffer_set_t *data_set)
66 krb5_error_code kret = 0;
68 krb5_gss_ctx_id_t ctx = (krb5_gss_ctx_id_t)context_handle;
74 retval = GSS_S_FAILURE;
76 *data_set = GSS_C_NO_BUFFER_SET;
78 retval = generic_gss_oid_decompose(minor_status,
79 GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID,
80 GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH,
83 if (GSS_ERROR(retval))
86 /* Externalize a structure of the right version */
89 kret = make_external_lucid_ctx_v1((krb5_pointer)ctx,
93 kret = (OM_uint32) KG_LUCID_VERSION;
101 rep.length = sizeof(lctx);
103 retval = generic_gss_add_buffer_set_member(minor_status, &rep, data_set);
104 if (GSS_ERROR(retval))
108 if (*minor_status == 0)
109 *minor_status = (OM_uint32) kret;
114 * Frees the storage associated with an
115 * exported lucid context structure.
118 gss_krb5int_free_lucid_sec_context(
119 OM_uint32 *minor_status,
120 const gss_OID desired_mech,
121 const gss_OID desired_object,
125 krb5_error_code kret = 0;
130 retval = GSS_S_FAILURE;
139 /* Determine version and call correct free routine */
140 version = ((gss_krb5_lucid_context_version_t *)kctx)->version;
143 free_external_lucid_ctx_v1((gss_krb5_lucid_context_v1_t*) kctx);
155 retval = GSS_S_COMPLETE;
160 if (*minor_status == 0)
161 *minor_status = (OM_uint32) kret;
169 static krb5_error_code
170 make_external_lucid_ctx_v1(
171 krb5_gss_ctx_id_rec * gctx,
175 gss_krb5_lucid_context_v1_t *lctx = NULL;
176 unsigned int bufsize = sizeof(gss_krb5_lucid_context_v1_t);
177 krb5_error_code retval;
179 /* Allocate the structure */
180 if ((lctx = xmalloc(bufsize)) == NULL) {
185 memset(lctx, 0, bufsize);
188 lctx->initiate = gctx->initiate ? 1 : 0;
189 lctx->endtime = gctx->krb_times.endtime;
190 lctx->send_seq = gctx->seq_send;
191 lctx->recv_seq = gctx->seq_recv;
192 lctx->protocol = gctx->proto;
193 /* gctx->proto == 0 ==> rfc1964-style key information
194 gctx->proto == 1 ==> cfx-style (draft-ietf-krb-wg-gssapi-cfx-07) keys */
195 if (gctx->proto == 0) {
196 lctx->rfc1964_kd.sign_alg = gctx->signalg;
197 lctx->rfc1964_kd.seal_alg = gctx->sealalg;
199 if ((retval = copy_keyblock_to_lucid_key(&gctx->seq->keyblock,
200 &lctx->rfc1964_kd.ctx_key)))
203 else if (gctx->proto == 1) {
205 /* (subkey is always present, either a copy of the kerberos
206 session key or a subkey) */
207 if ((retval = copy_keyblock_to_lucid_key(&gctx->subkey->keyblock,
208 &lctx->cfx_kd.ctx_key)))
210 if (gctx->have_acceptor_subkey) {
211 if ((retval = copy_keyblock_to_lucid_key(&gctx->acceptor_subkey->keyblock,
212 &lctx->cfx_kd.acceptor_subkey)))
214 lctx->cfx_kd.have_acceptor_subkey = 1;
218 return EINVAL; /* XXX better error code? */
227 free_external_lucid_ctx_v1(lctx);
233 /* Copy the contents of a krb5_keyblock to a gss_krb5_lucid_key_t structure */
234 static krb5_error_code
235 copy_keyblock_to_lucid_key(
236 krb5_keyblock *k5key,
237 gss_krb5_lucid_key_t *lkey)
239 if (!k5key || !k5key->contents || k5key->length == 0)
242 memset(lkey, 0, sizeof(gss_krb5_lucid_key_t));
244 /* Allocate storage for the key data */
245 if ((lkey->data = xmalloc(k5key->length)) == NULL) {
248 memcpy(lkey->data, k5key->contents, k5key->length);
249 lkey->length = k5key->length;
250 lkey->type = k5key->enctype;
256 /* Free any storage associated with a gss_krb5_lucid_key_t structure */
259 gss_krb5_lucid_key_t *key)
262 if (key->data && key->length) {
263 memset(key->data, 0, key->length);
265 memset(key, 0, sizeof(gss_krb5_lucid_key_t));
269 /* Free any storage associated with a gss_krb5_lucid_context_v1 structure */
271 free_external_lucid_ctx_v1(
272 gss_krb5_lucid_context_v1_t *ctx)
275 if (ctx->protocol == 0) {
276 free_lucid_key_data(&ctx->rfc1964_kd.ctx_key);
278 if (ctx->protocol == 1) {
279 free_lucid_key_data(&ctx->cfx_kd.ctx_key);
280 if (ctx->cfx_kd.have_acceptor_subkey)
281 free_lucid_key_data(&ctx->cfx_kd.acceptor_subkey);