mk_req_ext.c (505d05c7) mk_req_ext.c (159d09a2)
1/*
1/*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
3 * Use is subject to license terms.
4 */
5
6#pragma ident "%Z%%M% %I% %E% SMI"
7
8/*
9 * lib/krb5/krb/mk_req_ext.c
10 *
11 * Copyright 1990,1991 by the Massachusetts Institute of Technology.
12 * All Rights Reserved.
13 *
14 * Export of this software from the United States of America may
15 * require a specific license from the United States Government.
16 * It is the responsibility of any person or organization contemplating
17 * export to obtain such a license before exporting.
6
7/*
8 * lib/krb5/krb/mk_req_ext.c
9 *
10 * Copyright 1990,1991 by the Massachusetts Institute of Technology.
11 * All Rights Reserved.
12 *
13 * Export of this software from the United States of America may
14 * require a specific license from the United States Government.
15 * It is the responsibility of any person or organization contemplating
16 * export to obtain such a license before exporting.
18 *
17 *
19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
20 * distribute this software and its documentation for any purpose and
21 * without fee is hereby granted, provided that the above copyright
22 * notice appear in all copies and that both that copyright notice and
23 * this permission notice appear in supporting documentation, and that
24 * the name of M.I.T. not be used in advertising or publicity pertaining
25 * to distribution of the software without specific, written prior
26 * permission. Furthermore if you modify this software you must label
27 * your software as modified software and not distribute it in such a
28 * fashion that it might be confused with the original M.I.T. software.
29 * M.I.T. makes no representations about the suitability of
30 * this software for any purpose. It is provided "as is" without express
31 * or implied warranty.
18 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
19 * distribute this software and its documentation for any purpose and
20 * without fee is hereby granted, provided that the above copyright
21 * notice appear in all copies and that both that copyright notice and
22 * this permission notice appear in supporting documentation, and that
23 * the name of M.I.T. not be used in advertising or publicity pertaining
24 * to distribution of the software without specific, written prior
25 * permission. Furthermore if you modify this software you must label
26 * your software as modified software and not distribute it in such a
27 * fashion that it might be confused with the original M.I.T. software.
28 * M.I.T. makes no representations about the suitability of
29 * this software for any purpose. It is provided "as is" without express
30 * or implied warranty.
31 *
32 *
32 *
33 *
34 * krb5_mk_req_extended()
35 */
36
37
33 * krb5_mk_req_extended()
34 */
35
36
38#include <k5-int.h>
39#include <auth_con.h>
37#include "k5-int.h"
38#include "auth_con.h"
40
41/*
42 Formats a KRB_AP_REQ message into outbuf, with more complete options than
43 krb_mk_req.
44
45 outbuf, ap_req_options, checksum, and ccache are used in the
46 same fashion as for krb5_mk_req.
47

--- 18 unchanged lines hidden (view full) ---

66
67 On an error return, the credentials pointed to by creds might have been
68 augmented with additional fields from the obtained credentials; the entire
69 credentials should be released by calling krb5_free_creds().
70
71 returns system errors
72*/
73
39
40/*
41 Formats a KRB_AP_REQ message into outbuf, with more complete options than
42 krb_mk_req.
43
44 outbuf, ap_req_options, checksum, and ccache are used in the
45 same fashion as for krb5_mk_req.
46

--- 18 unchanged lines hidden (view full) ---

65
66 On an error return, the credentials pointed to by creds might have been
67 augmented with additional fields from the obtained credentials; the entire
68 credentials should be released by calling krb5_free_creds().
69
70 returns system errors
71*/
72
74static krb5_error_code
73static krb5_error_code
75krb5_generate_authenticator (krb5_context,
76 krb5_authenticator *, krb5_principal,
77 krb5_checksum *, krb5_keyblock *,
78 krb5_ui_4, krb5_authdata ** );
79
80krb5_error_code
81krb5int_generate_and_save_subkey (krb5_context context,
82 krb5_auth_context auth_context,
83 krb5_keyblock *keyblock)
84{
85#if 0
86 /*
87 * Solaris Kerberos: Don't bother with this PRNG stuff,
88 * we have /dev/random and PKCS#11 to handle Random Numbers.
89 */
90 /* Provide some more fodder for random number code.
74krb5_generate_authenticator (krb5_context,
75 krb5_authenticator *, krb5_principal,
76 krb5_checksum *, krb5_keyblock *,
77 krb5_ui_4, krb5_authdata ** );
78
79krb5_error_code
80krb5int_generate_and_save_subkey (krb5_context context,
81 krb5_auth_context auth_context,
82 krb5_keyblock *keyblock)
83{
84#if 0
85 /*
86 * Solaris Kerberos: Don't bother with this PRNG stuff,
87 * we have /dev/random and PKCS#11 to handle Random Numbers.
88 */
89 /* Provide some more fodder for random number code.
91 This isn't strong cryptographically; the point here is not
92 to guarantee randomness, but to make it less likely that multiple
93 sessions could pick the same subkey. */
90 This isn't strong cryptographically; the point here is not
91 to guarantee randomness, but to make it less likely that multiple
92 sessions could pick the same subkey. */
94 struct {
95 krb5_int32 sec, usec;
96 } rnd_data;
97 krb5_data d;
98
99 krb5_crypto_us_timeofday (&rnd_data.sec, &rnd_data.usec);
100 d.length = sizeof (rnd_data);
101 d.data = (char *) &rnd_data;
102 (void) krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_TIMING, &d);
103#endif
104 krb5_error_code retval;
105
93 struct {
94 krb5_int32 sec, usec;
95 } rnd_data;
96 krb5_data d;
97
98 krb5_crypto_us_timeofday (&rnd_data.sec, &rnd_data.usec);
99 d.length = sizeof (rnd_data);
100 d.data = (char *) &rnd_data;
101 (void) krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_TIMING, &d);
102#endif
103 krb5_error_code retval;
104
105 /* Solaris Kerberos */
106 if (auth_context->send_subkey != NULL) {
107 krb5_free_keyblock(context, auth_context->send_subkey);
108 auth_context->send_subkey = NULL;
109 }
110
111 if ((retval = krb5_generate_subkey(context, keyblock, &auth_context->send_subkey)))
112 return retval;
113
106 if (auth_context->send_subkey != NULL) {
107 krb5_free_keyblock(context, auth_context->send_subkey);
108 auth_context->send_subkey = NULL;
109 }
110
111 if ((retval = krb5_generate_subkey(context, keyblock, &auth_context->send_subkey)))
112 return retval;
113
114 /* Solaris Kerberos */
114 if (auth_context->recv_subkey != NULL) {
115 krb5_free_keyblock(context, auth_context->recv_subkey);
116 auth_context->recv_subkey = NULL;
117 }
118 retval = krb5_copy_keyblock(context, auth_context->send_subkey,
119 &auth_context->recv_subkey);
120 if (retval) {
121 krb5_free_keyblock(context, auth_context->send_subkey);
122 auth_context->send_subkey = NULL;
123 return retval;
124 }
125 return 0;
126}
127
128krb5_error_code KRB5_CALLCONV
115 if (auth_context->recv_subkey != NULL) {
116 krb5_free_keyblock(context, auth_context->recv_subkey);
117 auth_context->recv_subkey = NULL;
118 }
119 retval = krb5_copy_keyblock(context, auth_context->send_subkey,
120 &auth_context->recv_subkey);
121 if (retval) {
122 krb5_free_keyblock(context, auth_context->send_subkey);
123 auth_context->send_subkey = NULL;
124 return retval;
125 }
126 return 0;
127}
128
129krb5_error_code KRB5_CALLCONV
129krb5_mk_req_extended(
130 krb5_context context,
131 krb5_auth_context * auth_context,
132 const krb5_flags ap_req_options,
133 krb5_data * in_data,
134 krb5_creds * in_creds,
135 krb5_data * outbuf)
130krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
131 krb5_flags ap_req_options, krb5_data *in_data,
132 krb5_creds *in_creds, krb5_data *outbuf)
136{
137 krb5_error_code retval;
138 krb5_checksum checksum;
139 krb5_checksum *checksump = 0;
140 krb5_auth_context new_auth_context;
141
142 krb5_ap_req request;
143 krb5_data *scratch = 0;
144 krb5_data *toutbuf;
145
146 request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK;
147 request.authenticator.ciphertext.data = 0;
148 request.ticket = 0;
133{
134 krb5_error_code retval;
135 krb5_checksum checksum;
136 krb5_checksum *checksump = 0;
137 krb5_auth_context new_auth_context;
138
139 krb5_ap_req request;
140 krb5_data *scratch = 0;
141 krb5_data *toutbuf;
142
143 request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK;
144 request.authenticator.ciphertext.data = 0;
145 request.ticket = 0;
149
150 if (!in_creds->ticket.length)
146
147 if (!in_creds->ticket.length)
151 return(KRB5_NO_TKT_SUPPLIED);
152
153 /* we need a native ticket */
154 if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket)))
155 return(retval);
148 return(KRB5_NO_TKT_SUPPLIED);
149
150 /* we need a native ticket */
151 if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket)))
152 return(retval);
156
153
157 /* verify that the ticket is not expired */
154 /* verify that the ticket is not expired */
158 if ((retval = krb5_validate_times(context, &in_creds->times)))
155 if ((retval = krb5_validate_times(context, &in_creds->times)) != 0)
159 goto cleanup;
160
161 /* generate auth_context if needed */
162 if (*auth_context == NULL) {
163 if ((retval = krb5_auth_con_init(context, &new_auth_context)))
164 goto cleanup;
165 *auth_context = new_auth_context;
166 }
167
156 goto cleanup;
157
158 /* generate auth_context if needed */
159 if (*auth_context == NULL) {
160 if ((retval = krb5_auth_con_init(context, &new_auth_context)))
161 goto cleanup;
162 *auth_context = new_auth_context;
163 }
164
168 /* set auth context keyblock */
169 if ((*auth_context)->keyblock != NULL) {
170 krb5_free_keyblock(context, (*auth_context)->keyblock);
171 (*auth_context)->keyblock = NULL;
172 }
165 if ((*auth_context)->keyblock != NULL) {
166 krb5_free_keyblock(context, (*auth_context)->keyblock);
167 (*auth_context)->keyblock = NULL;
168 }
173 if ((retval = krb5_copy_keyblock(context, &in_creds->keyblock,
169
170 /* set auth context keyblock */
171 if ((retval = krb5_copy_keyblock(context, &in_creds->keyblock,
174 &((*auth_context)->keyblock))))
175 goto cleanup;
176
177 /* generate seq number if needed */
178 if ((((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
179 || ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
172 &((*auth_context)->keyblock))))
173 goto cleanup;
174
175 /* generate seq number if needed */
176 if ((((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
177 || ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
180 && ((*auth_context)->local_seq_number == 0))
178 && ((*auth_context)->local_seq_number == 0))
181 if ((retval = krb5_generate_seq_number(context, &in_creds->keyblock,
182 &(*auth_context)->local_seq_number)))
183 goto cleanup;
184
185
186 /* generate subkey if needed */
187 if (!in_data &&(*auth_context)->checksum_func) {
179 if ((retval = krb5_generate_seq_number(context, &in_creds->keyblock,
180 &(*auth_context)->local_seq_number)))
181 goto cleanup;
182
183
184 /* generate subkey if needed */
185 if (!in_data &&(*auth_context)->checksum_func) {
188 retval = (*auth_context)->checksum_func(context,
189 *auth_context,
190 (*auth_context)->checksum_func_data,
191 &in_data);
186 retval = (*auth_context)->checksum_func( context,
187 *auth_context,
188 (*auth_context)->checksum_func_data,
189 &in_data);
192 if (retval)
190 if (retval)
193 goto cleanup;
191 goto cleanup;
194 }
195
196 if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->send_subkey)) {
197 retval = krb5int_generate_and_save_subkey (context, *auth_context,
192 }
193
194 if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->send_subkey)) {
195 retval = krb5int_generate_and_save_subkey (context, *auth_context,
198 &in_creds->keyblock);
196 &in_creds->keyblock);
199 if (retval)
197 if (retval)
200 goto cleanup;
198 goto cleanup;
201 }
202
199 }
200
201
203 if (in_data) {
202 if (in_data) {
204 if ((*auth_context)->req_cksumtype == 0x8003) {
203
204 if ((*auth_context)->req_cksumtype == 0x8003) {
205 /* XXX Special hack for GSSAPI */
206 checksum.checksum_type = 0x8003;
207 checksum.length = in_data->length;
208 checksum.contents = (krb5_octet *) in_data->data;
209 } else {
205 /* XXX Special hack for GSSAPI */
206 checksum.checksum_type = 0x8003;
207 checksum.length = in_data->length;
208 checksum.contents = (krb5_octet *) in_data->data;
209 } else {
210 retval = krb5_c_make_checksum(context,
210 if ((retval = krb5_c_make_checksum(context,
211 (*auth_context)->req_cksumtype,
212 (*auth_context)->keyblock,
213 KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
211 (*auth_context)->req_cksumtype,
212 (*auth_context)->keyblock,
213 KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
214 in_data, &checksum);
215 if (retval)
214 in_data, &checksum)))
216 goto cleanup_cksum;
217 }
218 checksump = &checksum;
219 }
220
221 /* Generate authenticator */
222 if (((*auth_context)->authentp = (krb5_authenticator *)malloc(sizeof(
223 krb5_authenticator))) == NULL) {

--- 8 unchanged lines hidden (view full) ---

232 (*auth_context)->local_seq_number,
233 (in_creds)->authdata)))
234 goto cleanup_cksum;
235
236 /* encode the authenticator */
237 if ((retval = encode_krb5_authenticator((*auth_context)->authentp,
238 &scratch)))
239 goto cleanup_cksum;
215 goto cleanup_cksum;
216 }
217 checksump = &checksum;
218 }
219
220 /* Generate authenticator */
221 if (((*auth_context)->authentp = (krb5_authenticator *)malloc(sizeof(
222 krb5_authenticator))) == NULL) {

--- 8 unchanged lines hidden (view full) ---

231 (*auth_context)->local_seq_number,
232 (in_creds)->authdata)))
233 goto cleanup_cksum;
234
235 /* encode the authenticator */
236 if ((retval = encode_krb5_authenticator((*auth_context)->authentp,
237 &scratch)))
238 goto cleanup_cksum;
240
239
241 /* Null out these fields, to prevent pointer sharing problems;
242 * they were supplied by the caller
243 */
244 (*auth_context)->authentp->client = NULL;
245 (*auth_context)->authentp->checksum = NULL;
246 (*auth_context)->authentp->authorization_data = NULL;
247
248 /* call the encryption routine */
240 /* Null out these fields, to prevent pointer sharing problems;
241 * they were supplied by the caller
242 */
243 (*auth_context)->authentp->client = NULL;
244 (*auth_context)->authentp->checksum = NULL;
245 (*auth_context)->authentp->authorization_data = NULL;
246
247 /* call the encryption routine */
249 retval = krb5_encrypt_helper(context, &in_creds->keyblock,
248 if ((retval = krb5_encrypt_helper(context, &in_creds->keyblock,
250 KRB5_KEYUSAGE_AP_REQ_AUTH,
249 KRB5_KEYUSAGE_AP_REQ_AUTH,
251 scratch, &request.authenticator);
252 if (retval)
250 scratch, &request.authenticator)))
253 goto cleanup_cksum;
254
255 if ((retval = encode_krb5_ap_req(&request, &toutbuf)))
256 goto cleanup_cksum;
251 goto cleanup_cksum;
252
253 if ((retval = encode_krb5_ap_req(&request, &toutbuf)))
254 goto cleanup_cksum;
257#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
258 *outbuf = *toutbuf;
255 *outbuf = *toutbuf;
259#else
260 memcpy(outbuf, toutbuf, sizeof(krb5_data));
261#endif
262
263 krb5_xfree(toutbuf);
264
265cleanup_cksum:
266 if (checksump && checksump->checksum_type != 0x8003)
267 free(checksump->contents);
268
269cleanup:

--- 8 unchanged lines hidden (view full) ---

278 memset(scratch->data, 0, scratch->length);
279 krb5_xfree(scratch->data);
280 krb5_xfree(scratch);
281 }
282 return retval;
283}
284
285static krb5_error_code
256
257 krb5_xfree(toutbuf);
258
259cleanup_cksum:
260 if (checksump && checksump->checksum_type != 0x8003)
261 free(checksump->contents);
262
263cleanup:

--- 8 unchanged lines hidden (view full) ---

272 memset(scratch->data, 0, scratch->length);
273 krb5_xfree(scratch->data);
274 krb5_xfree(scratch);
275 }
276 return retval;
277}
278
279static krb5_error_code
286krb5_generate_authenticator(
287 krb5_context context,
288 krb5_authenticator *authent,
289 krb5_principal client,
290 krb5_checksum *cksum,
291 krb5_keyblock *key,
292 krb5_ui_4 seq_number,
293 krb5_authdata **authorization)
280krb5_generate_authenticator(krb5_context context, krb5_authenticator *authent, krb5_principal client, krb5_checksum *cksum, krb5_keyblock *key, krb5_ui_4 seq_number, krb5_authdata **authorization)
294{
295 krb5_error_code retval;
281{
282 krb5_error_code retval;
296
283
297 authent->client = client;
298 authent->checksum = cksum;
299 if (key) {
300 retval = krb5_copy_keyblock(context, key, &authent->subkey);
301 if (retval)
302 return retval;
303 } else
304 authent->subkey = 0;
305 authent->seq_number = seq_number;
306 authent->authorization_data = authorization;
307
308 return(krb5_us_timeofday(context, &authent->ctime, &authent->cusec));
309}
284 authent->client = client;
285 authent->checksum = cksum;
286 if (key) {
287 retval = krb5_copy_keyblock(context, key, &authent->subkey);
288 if (retval)
289 return retval;
290 } else
291 authent->subkey = 0;
292 authent->seq_number = seq_number;
293 authent->authorization_data = authorization;
294
295 return(krb5_us_timeofday(context, &authent->ctime, &authent->cusec));
296}