1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/gssapi/mechglue/g_export_cred.c - gss_export_cred definition */
3 /*
4 * Copyright (C) 2012 by the Massachusetts Institute of Technology.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "mglueP.h"
34
35 static OM_uint32
val_exp_cred_args(OM_uint32 * minor_status,gss_cred_id_t cred_handle,gss_buffer_t token)36 val_exp_cred_args(OM_uint32 *minor_status, gss_cred_id_t cred_handle,
37 gss_buffer_t token)
38 {
39
40 /* Initialize outputs. */
41 if (minor_status != NULL)
42 *minor_status = 0;
43 if (token != GSS_C_NO_BUFFER) {
44 token->length = 0;
45 token->value = NULL;
46 }
47
48 /* Validate arguments. */
49 if (minor_status == NULL)
50 return GSS_S_CALL_INACCESSIBLE_WRITE;
51 if (cred_handle == GSS_C_NO_CREDENTIAL)
52 return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED;
53 if (token == GSS_C_NO_BUFFER)
54 return GSS_S_CALL_INACCESSIBLE_WRITE;
55 return GSS_S_COMPLETE;
56 }
57
58 OM_uint32 KRB5_CALLCONV
gss_export_cred(OM_uint32 * minor_status,gss_cred_id_t cred_handle,gss_buffer_t token)59 gss_export_cred(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
60 gss_buffer_t token)
61 {
62 OM_uint32 status, tmpmin;
63 gss_union_cred_t cred;
64 gss_OID mech_oid;
65 gss_OID public_oid;
66 gss_mechanism mech;
67 gss_buffer_desc mech_token;
68 struct k5buf buf;
69 int i;
70
71 status = val_exp_cred_args(minor_status, cred_handle, token);
72 if (status != GSS_S_COMPLETE)
73 return status;
74
75 k5_buf_init_dynamic(&buf);
76
77 cred = (gss_union_cred_t) cred_handle;
78 for (i = 0; i < cred->count; i++) {
79 /* Get an export token for this mechanism. */
80 mech_oid = &cred->mechs_array[i];
81 public_oid = gssint_get_public_oid(mech_oid);
82 mech = gssint_get_mechanism(mech_oid);
83 if (public_oid == GSS_C_NO_OID || mech == NULL) {
84 status = GSS_S_DEFECTIVE_CREDENTIAL;
85 goto error;
86 }
87 if (mech->gss_export_cred == NULL) {
88 status = GSS_S_UNAVAILABLE;
89 goto error;
90 }
91 status = mech->gss_export_cred(minor_status, cred->cred_array[i],
92 &mech_token);
93 if (status != GSS_S_COMPLETE) {
94 map_error(minor_status, mech);
95 goto error;
96 }
97
98 /* Append the mech OID and token to buf. */
99 k5_buf_add_uint32_be(&buf, public_oid->length);
100 k5_buf_add_len(&buf, public_oid->elements, public_oid->length);
101 k5_buf_add_uint32_be(&buf, mech_token.length);
102 k5_buf_add_len(&buf, mech_token.value, mech_token.length);
103 gss_release_buffer(&tmpmin, &mech_token);
104 }
105
106 return k5buf_to_gss(minor_status, &buf, token);
107
108 error:
109 k5_buf_free(&buf);
110 return status;
111 }
112