1/*
2 * lib/gssapi/krb5/export_sec_context.c
3 *
4 * Copyright 1995 by the Massachusetts Institute of Technology.
5 * All Rights Reserved.
6 *
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.
11 *
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.
25 *
26 */
27
28/*
29 * export_sec_context.c	- Externalize the security context.
30 */
31#include "gssapiP_krb5.h"
32
33OM_uint32
34krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token)
35    OM_uint32		*minor_status;
36    gss_ctx_id_t	*context_handle;
37    gss_buffer_t	interprocess_token;
38{
39    krb5_context	context;
40    krb5_error_code	kret;
41    OM_uint32		retval;
42    size_t		bufsize, blen;
43    krb5_gss_ctx_id_t	ctx;
44    krb5_octet		*obuffer, *obp;
45
46    /* Assume a tragic failure */
47    obuffer = (krb5_octet *) NULL;
48    retval = GSS_S_FAILURE;
49    *minor_status = 0;
50
51    if (!kg_validate_ctx_id(*context_handle)) {
52	    kret = (OM_uint32) G_VALIDATE_FAILED;
53	    retval = GSS_S_NO_CONTEXT;
54	    goto error_out;
55    }
56
57    ctx = (krb5_gss_ctx_id_t) *context_handle;
58    context = ctx->k5_context;
59    kret = krb5_gss_ser_init(context);
60    if (kret)
61	goto error_out;
62
63    /* Determine size needed for externalization of context */
64    bufsize = 0;
65    if ((kret = kg_ctx_size(context, (krb5_pointer) ctx,
66			    &bufsize)))
67	    goto error_out;
68
69    /* Allocate the buffer */
70    if ((obuffer = (krb5_octet *) xmalloc(bufsize)) == NULL) {
71	    kret = ENOMEM;
72	    goto error_out;
73    }
74
75    obp = obuffer;
76    blen = bufsize;
77    /* Externalize the context */
78    if ((kret = kg_ctx_externalize(context,
79				   (krb5_pointer) ctx, &obp, &blen)))
80	    goto error_out;
81
82    /* Success!  Return the buffer */
83    interprocess_token->length = bufsize - blen;
84    interprocess_token->value = obuffer;
85    *minor_status = 0;
86    retval = GSS_S_COMPLETE;
87
88    /* Now, clean up the context state */
89    (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
90    *context_handle = GSS_C_NO_CONTEXT;
91
92    return (GSS_S_COMPLETE);
93
94error_out:
95    if (retval != GSS_S_COMPLETE)
96        if (kret != 0 && context != 0)
97	    save_error_info((OM_uint32)kret, context);
98    if (obuffer && bufsize) {
99	    memset(obuffer, 0, bufsize);
100	    xfree(obuffer);
101    }
102    if (*minor_status == 0)
103	    *minor_status = (OM_uint32) kret;
104    return(retval);
105}
106