xref: /freebsd/crypto/krb5/src/lib/gssapi/mechglue/g_export_cred.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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