5 * Copyright 1990 by the Massachusetts Institute of Technology.
7 * For copying and distribution information, please see the file
8 * <krb5/mit-copyright.h>.
10 * krb5_mk_req_extended()
13 #if !defined(lint) && !defined(SABER)
14 static char mk_req_ext_c[] =
16 #endif /* !lint & !SABER */
18 #include <krb5/copyright.h>
19 #include <krb5/krb5.h>
20 #include <krb5/krb5_err.h>
21 #include <krb5/asn1.h>
23 #include <krb5/libos.h>
25 #include <krb5/libos-proto.h>
27 #include <krb5/ext-proto.h>
31 Formats a KRB_AP_REQ message into outbuf, with more complete options than
34 outbuf, ap_req_options, checksum, and ccache are used in the
35 same fashion as for krb5_mk_req.
37 creds is used to supply the credentials (ticket and session key) needed
40 if creds->ticket has no data (length == 0), then a ticket is obtained
41 from either the cache or the TGS, passing creds to krb5_get_credentials().
42 kdc_options specifies the options requested for the ticket to be used.
43 If a ticket with appropriate flags is not found in the cache, then these
44 options are passed on in a request to an appropriate KDC.
46 ap_req_options specifies the KRB_AP_REQ options desired.
48 if ap_req_options specifies AP_OPTS_USE_SESSION_KEY, then creds->ticket
49 must contain the appropriate ENC-TKT-IN-SKEY ticket.
51 checksum specifies the checksum to be used in the authenticator.
53 The outbuf buffer storage is allocated, and should be freed by the
58 static krb5_error_code generate_authenticator PROTOTYPE((krb5_authenticator *,
60 const krb5_checksum *));
63 krb5_mk_req_extended(ap_req_options, checksum, times, kdc_options, ccache,
65 const krb5_flags ap_req_options;
66 const krb5_checksum *checksum;
67 const krb5_ticket_times *times;
68 const krb5_flags kdc_options;
73 krb5_error_code retval;
75 krb5_authenticator authent;
78 krb5_encrypt_block eblock;
80 if ((ap_req_options & AP_OPTS_USE_SESSION_KEY) &&
81 !creds->ticket.length)
82 return(KRB5_NO_TKT_SUPPLIED);
84 if (!creds->ticket.length) {
86 creds->times = *times; /* XXX do we need times? */
87 if (retval = krb5_get_credentials(kdc_options,
92 /* verify a valid etype is available */
93 if (!valid_keytype(creds->keyblock.keytype))
94 return KRB5_PROG_KEYTYPE_NOSUPP;
96 etype = krb5_keytype_array[creds->keyblock.keytype]->system->proto_enctype;
98 if (!valid_etype(etype))
99 return KRB5_PROG_ETYPE_NOSUPP;
101 request.ap_options = ap_req_options;
102 /* we need a native ticket */
103 if (retval = krb5_decode_ticket(&creds->ticket, &request.ticket))
104 return(retval); /* XXX who cleans up creds? */
106 #define cleanup_ticket() krb5_free_ticket(request.ticket)
107 if (retval = generate_authenticator(&authent, creds, checksum)) {
111 /* encode it before encrypting */
112 retval = encode_krb5_authenticator(&authent, &scratch);
117 #define cleanup_scratch() { (void) bzero(scratch->data, scratch->length); krb5_free_data(scratch); }
119 /* put together an eblock for this encryption */
121 eblock.crypto_entry = krb5_csarray[etype]->system;
122 request.authenticator.length = krb5_encrypt_size(scratch->length,
123 eblock.crypto_entry);
124 if (!(request.authenticator.data = malloc(request.authenticator.length))) {
129 #define cleanup_encpart() {(void) bzero(request.authenticator.data, request.authenticator.length); free(request.authenticator.data); request.authenticator.length = 0; request.authenticator.data = 0;}
131 /* do any necessary key pre-processing */
132 if (retval = (*eblock.crypto_entry->process_key)(&eblock,
137 #define cleanup_prockey() {(void) (*eblock.crypto_entry->finish_key)(&eblock);}
139 /* call the encryption routine */
141 (*eblock.crypto_entry->encrypt_func)((krb5_pointer) scratch->data,
142 (krb5_pointer) request.authenticator.data,
143 scratch->length, &eblock)) {
147 /* authenticator now assembled-- do some cleanup */
150 if (retval = (*eblock.crypto_entry->finish_key)(&eblock)) {
155 retval = encode_krb5_ap_req(&request, &outbuf);
171 static krb5_error_code
172 generate_authenticator(authent, creds, cksum)
173 krb5_authenticator *authent;
174 const krb5_creds *creds;
175 const krb5_checksum *cksum;
177 authent->client = creds->client;
178 authent->checksum = cksum;
179 return(krb5_ms_timeofday(&authent->ctime, &authent->cmsec));