2 * lib/krb5/krb/mk_req_ext.c
4 * Copyright 1990,1991 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. M.I.T. makes no representations about the suitability of
20 * this software for any purpose. It is provided "as is" without express
21 * or implied warranty.
24 * krb5_mk_req_extended()
32 Formats a KRB_AP_REQ message into outbuf, with more complete options than
35 outbuf, ap_req_options, checksum, and ccache are used in the
36 same fashion as for krb5_mk_req.
38 creds is used to supply the credentials (ticket and session key) needed
41 if creds->ticket has no data (length == 0), then a ticket is obtained
42 from either the cache or the TGS, passing creds to krb5_get_credentials().
43 kdc_options specifies the options requested for the ticket to be used.
44 If a ticket with appropriate flags is not found in the cache, then these
45 options are passed on in a request to an appropriate KDC.
47 ap_req_options specifies the KRB_AP_REQ options desired.
49 if ap_req_options specifies AP_OPTS_USE_SESSION_KEY, then creds->ticket
50 must contain the appropriate ENC-TKT-IN-SKEY ticket.
52 checksum specifies the checksum to be used in the authenticator.
54 The outbuf buffer storage is allocated, and should be freed by the
57 On an error return, the credentials pointed to by creds might have been
58 augmented with additional fields from the obtained credentials; the entire
59 credentials should be released by calling krb5_free_creds().
64 static krb5_error_code
65 krb5_generate_authenticator PROTOTYPE((krb5_context,
66 krb5_authenticator *, krb5_principal,
67 const krb5_checksum *, krb5_keyblock *,
68 krb5_int32, krb5_authdata ** ));
70 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
71 krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
74 krb5_auth_context FAR * auth_context;
75 const krb5_flags ap_req_options;
76 krb5_data FAR * in_data;
77 krb5_creds FAR * in_creds;
78 krb5_data FAR * outbuf;
80 krb5_error_code retval;
81 krb5_checksum checksum;
82 krb5_checksum *checksump = 0;
83 krb5_auth_context new_auth_context;
86 krb5_data *scratch = 0;
89 request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK;
90 request.authenticator.ciphertext.data = 0;
93 if (!in_creds->ticket.length)
94 return(KRB5_NO_TKT_SUPPLIED);
96 /* we need a native ticket */
97 if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket)))
100 /* verify that the ticket is not expired */
101 if ((retval = krb5_validate_times(context, &in_creds->times)) != 0)
104 /* generate auth_context if needed */
105 if (*auth_context == NULL) {
106 if ((retval = krb5_auth_con_init(context, &new_auth_context)))
108 *auth_context = new_auth_context;
111 /* set auth context keyblock */
112 if ((retval = krb5_copy_keyblock(context, &in_creds->keyblock,
113 &((*auth_context)->keyblock))))
116 /* generate seq number if needed */
117 if ((((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
118 || ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
119 && ((*auth_context)->local_seq_number == 0))
120 if ((retval = krb5_generate_seq_number(context, &in_creds->keyblock,
121 &(*auth_context)->local_seq_number)))
125 /* generate subkey if needed */
126 if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey))
127 if ((retval = krb5_generate_subkey(context, &(in_creds)->keyblock,
128 &(*auth_context)->local_subkey)))
132 if ((*auth_context)->req_cksumtype == 0x8003) {
133 /* XXX Special hack for GSSAPI */
134 checksum.checksum_type = 0x8003;
135 checksum.length = in_data->length;
136 checksum.contents = (krb5_octet *) in_data->data;
138 if ((retval = krb5_c_make_checksum(context,
139 (*auth_context)->req_cksumtype,
140 (*auth_context)->keyblock,
141 KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
142 in_data, &checksum)))
145 checksump = &checksum;
148 /* Generate authenticator */
149 if (((*auth_context)->authentp = (krb5_authenticator *)malloc(sizeof(
150 krb5_authenticator))) == NULL) {
155 if ((retval = krb5_generate_authenticator(context,
156 (*auth_context)->authentp,
157 (in_creds)->client, checksump,
158 (*auth_context)->local_subkey,
159 (*auth_context)->local_seq_number,
160 (in_creds)->authdata)))
163 /* encode the authenticator */
164 if ((retval = encode_krb5_authenticator((*auth_context)->authentp,
168 /* Null out these fields, to prevent pointer sharing problems;
169 * they were supplied by the caller
171 (*auth_context)->authentp->client = NULL;
172 (*auth_context)->authentp->checksum = NULL;
173 (*auth_context)->authentp->authorization_data = NULL;
175 /* call the encryption routine */
176 if ((retval = krb5_encrypt_helper(context, &in_creds->keyblock,
177 KRB5_KEYUSAGE_AP_REQ_AUTH,
178 scratch, &request.authenticator)))
181 if ((retval = encode_krb5_ap_req(&request, &toutbuf)))
183 #ifdef HAVE_C_STRUCTURE_ASSIGNMENT
186 memcpy(outbuf, toutbuf, sizeof(krb5_data));
192 if (checksump && checksump->checksum_type != 0x8003)
193 free(checksump->contents);
197 krb5_free_ticket(context, request.ticket);
198 if (request.authenticator.ciphertext.data) {
199 (void) memset(request.authenticator.ciphertext.data, 0,
200 request.authenticator.ciphertext.length);
201 free(request.authenticator.ciphertext.data);
204 memset(scratch->data, 0, scratch->length);
205 krb5_xfree(scratch->data);
211 static krb5_error_code
212 krb5_generate_authenticator(context, authent, client, cksum, key, seq_number, authorization)
213 krb5_context context;
214 krb5_authenticator *authent;
215 krb5_principal client;
216 const krb5_checksum *cksum;
218 krb5_int32 seq_number;
219 krb5_authdata **authorization;
221 krb5_error_code retval;
223 authent->client = client;
224 authent->checksum = (krb5_checksum *)cksum;
226 retval = krb5_copy_keyblock(context, key, &authent->subkey);
231 authent->seq_number = seq_number;
232 authent->authorization_data = authorization;
234 return(krb5_us_timeofday(context, &authent->ctime, &authent->cusec));