xref: /titanic_52/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.c (revision ba7b222e36bac28710a7f43739283302b617e7f5)
1 /*
2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 /* -*- mode: c; indent-tabs-mode: nil -*- */
6 /*
7  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
8  * Use is subject to license terms.
9  */
10 /*
11  * src/lib/krb5/asn.1/asn1_k_encode.c
12  *
13  * Copyright 1994, 2008 by the Massachusetts Institute of Technology.
14  * All Rights Reserved.
15  *
16  * Export of this software from the United States of America may
17  *   require a specific license from the United States Government.
18  *   It is the responsibility of any person or organization contemplating
19  *   export to obtain such a license before exporting.
20  *
21  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
22  * distribute this software and its documentation for any purpose and
23  * without fee is hereby granted, provided that the above copyright
24  * notice appear in all copies and that both that copyright notice and
25  * this permission notice appear in supporting documentation, and that
26  * the name of M.I.T. not be used in advertising or publicity pertaining
27  * to distribution of the software without specific, written prior
28  * permission.  Furthermore if you modify this software you must label
29  * your software as modified software and not distribute it in such a
30  * fashion that it might be confused with the original M.I.T. software.
31  * M.I.T. makes no representations about the suitability of
32  * this software for any purpose.  It is provided "as is" without express
33  * or implied warranty.
34  */
35 
36 #include "asn1_k_encode.h"
37 #include "asn1_make.h"
38 #include "asn1_encode.h"
39 #include <assert.h>
40 #include "k5-platform-store_32.h" /* Solaris Kerberos */
41 
42 /* helper macros
43 
44    These are mostly only needed for PKINIT, but there are three
45    basic-krb5 encoders not converted yet.  */
46 
47 /* setup() -- create and initialize bookkeeping variables
48      retval: stores error codes returned from subroutines
49      length: length of the most-recently produced encoding
50      sum: cumulative length of the entire encoding */
51 #define asn1_setup()\
52   asn1_error_code retval;\
53   unsigned int sum=0
54 
55 /* form a sequence (by adding a sequence header to the current encoding) */
56 #define asn1_makeseq()\
57 { unsigned int length;\
58   retval = asn1_make_sequence(buf,sum,&length);\
59   if (retval) {\
60     return retval; }\
61   sum += length; }
62 
63 /* produce the final output and clean up the workspace */
64 #define asn1_cleanup()\
65   *retlen = sum;\
66   return 0
67 
68 /* asn1_addfield -- add a field, or component, to the encoding */
69 #define asn1_addfield(value,tag,encoder)\
70 { unsigned int length; \
71   retval = encoder(buf,value,&length);  \
72   if (retval) {\
73     return retval; }\
74   sum += length;\
75   retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
76   if (retval) {\
77     return retval; }\
78   sum += length; }
79 
80 DEFINTTYPE(int32, krb5_int32);
81 DEFPTRTYPE(int32_ptr, int32);
82 
83 DEFUINTTYPE(uint, unsigned int);
84 DEFUINTTYPE(octet, krb5_octet);
85 DEFUINTTYPE(ui_4, krb5_ui_4);
86 
87 DEFFNLENTYPE(octetstring, unsigned char *, asn1_encode_octetstring);
88 DEFFNLENTYPE(s_octetstring, char *, asn1_encode_octetstring);
89 DEFFNLENTYPE(charstring, char *, asn1_encode_charstring);
90 DEFFNLENTYPE(generalstring, char *, asn1_encode_generalstring);
91 DEFFNLENTYPE(u_generalstring, unsigned char *, asn1_encode_generalstring);
92 DEFFNLENTYPE(opaque, char *, asn1_encode_opaque);
93 
94 DEFFIELDTYPE(gstring_data, krb5_data,
95              FIELDOF_STRING(krb5_data, generalstring, data, length, -1));
96 DEFPTRTYPE(gstring_data_ptr,gstring_data);
97 
98 DEFFIELDTYPE(ostring_data, krb5_data,
99              FIELDOF_STRING(krb5_data, s_octetstring, data, length, -1));
100 DEFPTRTYPE(ostring_data_ptr,ostring_data);
101 
102 DEFFIELDTYPE(opaque_data, krb5_data,
103              FIELDOF_STRING(krb5_data, opaque, data, length, -1));
104 
105 DEFFIELDTYPE(realm_of_principal_data, krb5_principal_data,
106              FIELDOF_NORM(krb5_principal_data, gstring_data, realm, -1));
107 DEFPTRTYPE(realm_of_principal, realm_of_principal_data);
108 
109 
110 static const struct field_info princname_fields[] = {
111     FIELDOF_NORM(krb5_principal_data, int32, type, 0),
112     FIELDOF_SEQOF_INT32(krb5_principal_data, gstring_data_ptr, data, length, 1),
113 };
114 /* krb5_principal is a typedef for krb5_principal_data*, so this is
115    effectively "encode_principal_data_at" with an address arg.  */
116 DEFSEQTYPE(principal_data, krb5_principal_data, princname_fields, 0);
117 DEFPTRTYPE(principal, principal_data);
118 
119 static asn1_error_code
120 asn1_encode_kerberos_time_at(asn1buf *buf, const krb5_timestamp *val,
121                              unsigned int *retlen)
122 {
123     /* Range checking for time_t vs krb5_timestamp?  */
124     time_t tval = *val;
125     return asn1_encode_generaltime(buf, tval, retlen);
126 }
127 DEFFNXTYPE(kerberos_time, krb5_timestamp, asn1_encode_kerberos_time_at);
128 
129 static const struct field_info address_fields[] = {
130     FIELDOF_NORM(krb5_address, int32, addrtype, 0),
131     FIELDOF_STRING(krb5_address, octetstring, contents, length, 1),
132 };
133 DEFSEQTYPE(address, krb5_address, address_fields, 0);
134 DEFPTRTYPE(address_ptr, address);
135 
136 DEFNULLTERMSEQOFTYPE(seq_of_host_addresses, address_ptr);
137 DEFPTRTYPE(ptr_seqof_host_addresses, seq_of_host_addresses);
138 
139 static unsigned int
140 optional_encrypted_data (const void *vptr)
141 {
142     const krb5_enc_data *val = vptr;
143     unsigned int optional = 0;
144 
145     if (val->kvno != 0)
146         optional |= (1u << 1);
147 
148     return optional;
149 }
150 
151 static const struct field_info encrypted_data_fields[] = {
152     FIELDOF_NORM(krb5_enc_data, int32, enctype, 0),
153     FIELDOF_OPT(krb5_enc_data, uint, kvno, 1, 1),
154     FIELDOF_NORM(krb5_enc_data, ostring_data, ciphertext, 2),
155 };
156 DEFSEQTYPE(encrypted_data, krb5_enc_data, encrypted_data_fields,
157            optional_encrypted_data);
158 
159 /* The encode_bitstring function wants an array of bytes (since PKINIT
160    may provide something that isn't 32 bits), but krb5_flags is stored
161    as a 32-bit integer in host order.  */
162 static asn1_error_code
163 asn1_encode_krb5_flags_at(asn1buf *buf, const krb5_flags *val,
164                           unsigned int *retlen)
165 {
166     unsigned char cbuf[4];
167     store_32_be((krb5_ui_4) *val, cbuf);
168     return asn1_encode_bitstring(buf, 4, cbuf, retlen);
169 }
170 DEFFNXTYPE(krb5_flags, krb5_flags, asn1_encode_krb5_flags_at);
171 
172 static const struct field_info authdata_elt_fields[] = {
173     /* ad-type[0]               INTEGER */
174     FIELDOF_NORM(krb5_authdata, int32, ad_type, 0),
175     /* ad-data[1]               OCTET STRING */
176     FIELDOF_STRING(krb5_authdata, octetstring, contents, length, 1),
177 };
178 DEFSEQTYPE(authdata_elt, krb5_authdata, authdata_elt_fields, 0);
179 DEFPTRTYPE(authdata_elt_ptr, authdata_elt);
180 DEFNONEMPTYNULLTERMSEQOFTYPE(auth_data, authdata_elt_ptr);
181 DEFPTRTYPE(auth_data_ptr, auth_data);
182 
183 static const struct field_info encryption_key_fields[] = {
184     FIELDOF_NORM(krb5_keyblock, int32, enctype, 0),
185     FIELDOF_STRING(krb5_keyblock, octetstring, contents, length, 1),
186 };
187 DEFSEQTYPE(encryption_key, krb5_keyblock, encryption_key_fields, 0);
188 DEFPTRTYPE(ptr_encryption_key, encryption_key);
189 
190 static const struct field_info checksum_fields[] = {
191     FIELDOF_NORM(krb5_checksum, int32, checksum_type, 0),
192     FIELDOF_STRING(krb5_checksum, octetstring, contents, length, 1),
193 };
194 DEFSEQTYPE(checksum, krb5_checksum, checksum_fields, 0);
195 DEFPTRTYPE(checksum_ptr, checksum);
196 DEFNULLTERMSEQOFTYPE(seq_of_checksum, checksum_ptr);
197 DEFPTRTYPE(ptr_seqof_checksum, seq_of_checksum);
198 
199 static const struct field_info lr_fields[] = {
200     FIELDOF_NORM(krb5_last_req_entry, int32, lr_type, 0),
201     FIELDOF_NORM(krb5_last_req_entry, kerberos_time, value, 1),
202 };
203 DEFSEQTYPE(last_req_ent, krb5_last_req_entry, lr_fields, 0);
204 
205 DEFPTRTYPE(last_req_ent_ptr, last_req_ent);
206 DEFNONEMPTYNULLTERMSEQOFTYPE(last_req, last_req_ent_ptr);
207 DEFPTRTYPE(last_req_ptr, last_req);
208 
209 static const struct field_info ticket_fields[] = {
210     FIELD_INT_IMM(KVNO, 0),
211     FIELDOF_NORM(krb5_ticket, realm_of_principal, server, 1),
212     FIELDOF_NORM(krb5_ticket, principal, server, 2),
213     FIELDOF_NORM(krb5_ticket, encrypted_data, enc_part, 3),
214 };
215 DEFSEQTYPE(untagged_ticket, krb5_ticket, ticket_fields, 0);
216 DEFAPPTAGGEDTYPE(ticket, 1, untagged_ticket);
217 
218 static const struct field_info pa_data_fields[] = {
219     FIELDOF_NORM(krb5_pa_data, int32, pa_type, 1),
220     FIELDOF_STRING(krb5_pa_data, octetstring, contents, length, 2),
221 };
222 DEFSEQTYPE(pa_data, krb5_pa_data, pa_data_fields, 0);
223 DEFPTRTYPE(pa_data_ptr, pa_data);
224 
225 DEFNULLTERMSEQOFTYPE(seq_of_pa_data, pa_data_ptr);
226 DEFPTRTYPE(ptr_seqof_pa_data, seq_of_pa_data);
227 
228 DEFPTRTYPE(ticket_ptr, ticket);
229 DEFNONEMPTYNULLTERMSEQOFTYPE(seq_of_ticket,ticket_ptr);
230 DEFPTRTYPE(ptr_seqof_ticket, seq_of_ticket);
231 
232 /* EncKDCRepPart ::= SEQUENCE */
233 static const struct field_info enc_kdc_rep_part_fields[] = {
234     /* key[0]           EncryptionKey */
235     FIELDOF_NORM(krb5_enc_kdc_rep_part, ptr_encryption_key, session, 0),
236     /* last-req[1]      LastReq */
237     FIELDOF_NORM(krb5_enc_kdc_rep_part, last_req_ptr, last_req, 1),
238     /* nonce[2]         INTEGER */
239     FIELDOF_NORM(krb5_enc_kdc_rep_part, int32, nonce, 2),
240     /* key-expiration[3]        KerberosTime OPTIONAL */
241     FIELDOF_OPT(krb5_enc_kdc_rep_part, kerberos_time, key_exp, 3, 3),
242     /* flags[4]         TicketFlags */
243     FIELDOF_NORM(krb5_enc_kdc_rep_part, krb5_flags, flags, 4),
244     /* authtime[5]      KerberosTime */
245     FIELDOF_NORM(krb5_enc_kdc_rep_part, kerberos_time, times.authtime, 5),
246     /* starttime[6]     KerberosTime OPTIONAL */
247     FIELDOF_OPT(krb5_enc_kdc_rep_part, kerberos_time, times.starttime, 6, 6),
248     /* endtime[7]               KerberosTime */
249     FIELDOF_NORM(krb5_enc_kdc_rep_part, kerberos_time, times.endtime, 7),
250     /* renew-till[8]    KerberosTime OPTIONAL */
251     FIELDOF_OPT(krb5_enc_kdc_rep_part, kerberos_time, times.renew_till, 8, 8),
252     /* srealm[9]                Realm */
253     FIELDOF_NORM(krb5_enc_kdc_rep_part, realm_of_principal, server, 9),
254     /* sname[10]                PrincipalName */
255     FIELDOF_NORM(krb5_enc_kdc_rep_part, principal, server, 10),
256     /* caddr[11]                HostAddresses OPTIONAL */
257     FIELDOF_OPT(krb5_enc_kdc_rep_part, ptr_seqof_host_addresses, caddrs,
258                 11, 11),
259     /* encrypted-pa-data[12]    SEQUENCE OF PA-DATA OPTIONAL */
260     FIELDOF_OPT(krb5_enc_kdc_rep_part, ptr_seqof_pa_data, enc_padata, 12, 12),
261 };
262 static unsigned int optional_enc_kdc_rep_part(const void *p)
263 {
264     const krb5_enc_kdc_rep_part *val = p;
265     unsigned int optional = 0;
266 
267     if (val->key_exp)
268         optional |= (1u << 3);
269     if (val->times.starttime)
270         optional |= (1u << 6);
271     if (val->flags & TKT_FLG_RENEWABLE)
272         optional |= (1u << 8);
273     if (val->caddrs != NULL && val->caddrs[0] != NULL)
274         optional |= (1u << 11);
275 
276     return optional;
277 }
278 DEFSEQTYPE(enc_kdc_rep_part, krb5_enc_kdc_rep_part, enc_kdc_rep_part_fields,
279            optional_enc_kdc_rep_part);
280 
281 /* Yuck!  Eventually push this *up* above the encoder API and make the
282    rest of the library put the realm name in one consistent place.  At
283    the same time, might as well add the msg-type field and encode both
284    AS-REQ and TGS-REQ through the same descriptor.  */
285 struct kdc_req_hack {
286     krb5_kdc_req v;
287     krb5_data *server_realm;
288 };
289 static const struct field_info kdc_req_hack_fields[] = {
290     FIELDOF_NORM(struct kdc_req_hack, krb5_flags, v.kdc_options, 0),
291     FIELDOF_OPT(struct kdc_req_hack, principal, v.client, 1, 1),
292     FIELDOF_NORM(struct kdc_req_hack, gstring_data_ptr, server_realm, 2),
293     FIELDOF_OPT(struct kdc_req_hack, principal, v.server, 3, 3),
294     FIELDOF_OPT(struct kdc_req_hack, kerberos_time, v.from, 4, 4),
295     FIELDOF_NORM(struct kdc_req_hack, kerberos_time, v.till, 5),
296     FIELDOF_OPT(struct kdc_req_hack, kerberos_time, v.rtime, 6, 6),
297     FIELDOF_NORM(struct kdc_req_hack, int32, v.nonce, 7),
298     FIELDOF_SEQOF_INT32(struct kdc_req_hack, int32_ptr, v.ktype, v.nktypes, 8),
299     FIELDOF_OPT(struct kdc_req_hack, ptr_seqof_host_addresses, v.addresses, 9, 9),
300     FIELDOF_OPT(struct kdc_req_hack, encrypted_data, v.authorization_data, 10, 10),
301     FIELDOF_OPT(struct kdc_req_hack, ptr_seqof_ticket, v.second_ticket, 11, 11),
302 };
303 static unsigned int optional_kdc_req_hack(const void *p)
304 {
305     const struct kdc_req_hack *val2 = p;
306     const krb5_kdc_req *val = &val2->v;
307     unsigned int optional = 0;
308 
309     if (val->second_ticket != NULL && val->second_ticket[0] != NULL)
310         optional |= (1u << 11);
311     if (val->authorization_data.ciphertext.data != NULL)
312         optional |= (1u << 10);
313     if (val->addresses != NULL && val->addresses[0] != NULL)
314         optional |= (1u << 9);
315     if (val->rtime)
316         optional |= (1u << 6);
317     if (val->from)
318         optional |= (1u << 4);
319     if (val->server != NULL)
320         optional |= (1u << 3);
321     if (val->client != NULL)
322         optional |= (1u << 1);
323 
324     return optional;
325 }
326 DEFSEQTYPE(kdc_req_body_hack, struct kdc_req_hack, kdc_req_hack_fields,
327            optional_kdc_req_hack);
328 static asn1_error_code
329 asn1_encode_kdc_req_hack(asn1buf *, const struct kdc_req_hack *,
330                          unsigned int *);
331 MAKE_ENCFN(asn1_encode_kdc_req_hack, kdc_req_body_hack);
332 static asn1_error_code
333 asn1_encode_kdc_req_body(asn1buf *buf, const krb5_kdc_req *val,
334                          unsigned int *retlen)
335 {
336     struct kdc_req_hack val2;
337     val2.v = *val;
338     if (val->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY) {
339         if (val->second_ticket != NULL && val->second_ticket[0] != NULL) {
340             val2.server_realm = &val->second_ticket[0]->server->realm;
341         } else return ASN1_MISSING_FIELD;
342     } else if (val->server != NULL) {
343         val2.server_realm = &val->server->realm;
344     } else return ASN1_MISSING_FIELD;
345     return asn1_encode_kdc_req_hack(buf, &val2, retlen);
346 }
347 DEFFNXTYPE(kdc_req_body, krb5_kdc_req, asn1_encode_kdc_req_body);
348 /* end ugly hack */
349 
350 DEFPTRTYPE(ptr_kdc_req_body,kdc_req_body);
351 
352 static const struct field_info transited_fields[] = {
353     FIELDOF_NORM(krb5_transited, octet, tr_type, 0),
354     FIELDOF_NORM(krb5_transited, ostring_data, tr_contents, 1),
355 };
356 DEFSEQTYPE(transited, krb5_transited, transited_fields, 0);
357 
358 static const struct field_info krb_safe_body_fields[] = {
359     FIELDOF_NORM(krb5_safe, ostring_data, user_data, 0),
360     FIELDOF_OPT(krb5_safe, kerberos_time, timestamp, 1, 1),
361     FIELDOF_OPT(krb5_safe, int32, usec, 2, 2),
362     FIELDOF_OPT(krb5_safe, uint, seq_number, 3, 3),
363     FIELDOF_NORM(krb5_safe, address_ptr, s_address, 4),
364     FIELDOF_OPT(krb5_safe, address_ptr, r_address, 5, 5),
365 };
366 static unsigned int optional_krb_safe_body(const void *p)
367 {
368     const krb5_safe *val = p;
369     unsigned int optional = 0;
370 
371     if (val->timestamp) {
372         optional |= (1u << 1);
373         optional |= (1u << 2);
374     }
375     if (val->seq_number)
376         optional |= (1u << 3);
377     if (val->r_address != NULL)
378         optional |= (1u << 5);
379 
380     return optional;
381 }
382 DEFSEQTYPE(krb_safe_body, krb5_safe, krb_safe_body_fields,
383            optional_krb_safe_body);
384 
385 static const struct field_info krb_cred_info_fields[] = {
386     FIELDOF_NORM(krb5_cred_info, ptr_encryption_key, session, 0),
387     FIELDOF_OPT(krb5_cred_info, realm_of_principal, client, 1, 1),
388     FIELDOF_OPT(krb5_cred_info, principal, client, 2, 2),
389     FIELDOF_OPT(krb5_cred_info, krb5_flags, flags, 3, 3),
390     FIELDOF_OPT(krb5_cred_info, kerberos_time, times.authtime, 4, 4),
391     FIELDOF_OPT(krb5_cred_info, kerberos_time, times.starttime, 5, 5),
392     FIELDOF_OPT(krb5_cred_info, kerberos_time, times.endtime, 6, 6),
393     FIELDOF_OPT(krb5_cred_info, kerberos_time, times.renew_till, 7, 7),
394     FIELDOF_OPT(krb5_cred_info, realm_of_principal, server, 8, 8),
395     FIELDOF_OPT(krb5_cred_info, principal, server, 9, 9),
396     FIELDOF_OPT(krb5_cred_info, ptr_seqof_host_addresses, caddrs, 10, 10),
397 };
398 static unsigned int optional_krb_cred_info(const void *p)
399 {
400     const krb5_cred_info *val = p;
401     unsigned int optional = 0;
402 
403     if (val->caddrs != NULL && val->caddrs[0] != NULL)
404         optional |= (1u << 10);
405     if (val->server != NULL) {
406         optional |= (1u << 9);
407         optional |= (1u << 8);
408     }
409     if (val->times.renew_till)
410         optional |= (1u << 7);
411     if (val->times.endtime)
412         optional |= (1u << 6);
413     if (val->times.starttime)
414         optional |= (1u << 5);
415     if (val->times.authtime)
416         optional |= (1u << 4);
417     if (val->flags)
418         optional |= (1u << 3);
419     if (val->client != NULL) {
420         optional |= (1u << 2);
421         optional |= (1u << 1);
422     }
423 
424     return optional;
425 }
426 DEFSEQTYPE(cred_info, krb5_cred_info, krb_cred_info_fields,
427            optional_krb_cred_info);
428 DEFPTRTYPE(cred_info_ptr, cred_info);
429 DEFNULLTERMSEQOFTYPE(seq_of_cred_info, cred_info_ptr);
430 
431 DEFPTRTYPE(ptrseqof_cred_info, seq_of_cred_info);
432 
433 
434 
435 static unsigned int
436 optional_etype_info_entry(const void *vptr)
437 {
438     const krb5_etype_info_entry *val = vptr;
439     unsigned int optional = 0;
440 
441     if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT)
442         optional |= (1u << 1);
443 
444     return optional;
445 }
446 static const struct field_info etype_info_entry_fields[] = {
447     FIELDOF_NORM(krb5_etype_info_entry, int32, etype, 0),
448     FIELDOF_OPTSTRING(krb5_etype_info_entry, octetstring, salt, length, 1, 1),
449 };
450 DEFSEQTYPE(etype_info_entry, krb5_etype_info_entry, etype_info_entry_fields,
451            optional_etype_info_entry);
452 
453 static unsigned int
454 optional_etype_info2_entry(const void *vptr)
455 {
456     const krb5_etype_info_entry *val = vptr;
457     unsigned int optional = 0;
458 
459     if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT)
460         optional |= (1u << 1);
461     if (val->s2kparams.data)
462         optional |= (1u << 2);
463 
464     return optional;
465 }
466 
467 static const struct field_info etype_info2_entry_fields[] = {
468     FIELDOF_NORM(krb5_etype_info_entry, int32, etype, 0),
469     FIELDOF_OPTSTRING(krb5_etype_info_entry, u_generalstring, salt, length,
470                       1, 1),
471     FIELDOF_OPT(krb5_etype_info_entry, ostring_data, s2kparams, 2, 2),
472 };
473 DEFSEQTYPE(etype_info2_entry, krb5_etype_info_entry, etype_info2_entry_fields,
474            optional_etype_info2_entry);
475 
476 DEFPTRTYPE(etype_info_entry_ptr, etype_info_entry);
477 DEFNULLTERMSEQOFTYPE(etype_info, etype_info_entry_ptr);
478 
479 DEFPTRTYPE(etype_info2_entry_ptr, etype_info2_entry);
480 DEFNULLTERMSEQOFTYPE(etype_info2, etype_info2_entry_ptr);
481 
482 static const struct field_info passwdsequence_fields[] = {
483     FIELDOF_NORM(passwd_phrase_element, ostring_data_ptr, passwd, 0),
484     FIELDOF_NORM(passwd_phrase_element, ostring_data_ptr, phrase, 1),
485 };
486 DEFSEQTYPE(passwdsequence, passwd_phrase_element, passwdsequence_fields, 0);
487 
488 DEFPTRTYPE(passwdsequence_ptr, passwdsequence);
489 DEFNONEMPTYNULLTERMSEQOFTYPE(seqof_passwdsequence, passwdsequence_ptr);
490 DEFPTRTYPE(ptr_seqof_passwdsequence, seqof_passwdsequence);
491 
492 
493 static const struct field_info sam_challenge_fields[] = {
494     FIELDOF_NORM(krb5_sam_challenge, int32, sam_type, 0),
495     FIELDOF_NORM(krb5_sam_challenge, krb5_flags, sam_flags, 1),
496     FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_type_name, 2, 2),
497     FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_track_id,3, 3),
498     FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_challenge_label,4, 4),
499     FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_challenge,5, 5),
500     FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_response_prompt,6, 6),
501     FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_pk_for_sad,7, 7),
502     FIELDOF_OPT(krb5_sam_challenge, int32, sam_nonce, 8, 8),
503     FIELDOF_OPT(krb5_sam_challenge, checksum, sam_cksum, 9, 9),
504 };
505 static unsigned int optional_sam_challenge(const void *p)
506 {
507     const krb5_sam_challenge *val = p;
508     unsigned int optional = 0;
509 
510     if (val->sam_cksum.length)
511         optional |= (1u << 9);
512 
513     if (val->sam_nonce)
514         optional |= (1u << 8);
515 
516     if (val->sam_pk_for_sad.length > 0) optional |= (1u << 7);
517     if (val->sam_response_prompt.length > 0) optional |= (1u << 6);
518     if (val->sam_challenge.length > 0) optional |= (1u << 5);
519     if (val->sam_challenge_label.length > 0) optional |= (1u << 4);
520     if (val->sam_track_id.length > 0) optional |= (1u << 3);
521     if (val->sam_type_name.length > 0) optional |= (1u << 2);
522 
523     return optional;
524 }
525 DEFSEQTYPE(sam_challenge,krb5_sam_challenge,sam_challenge_fields,
526            optional_sam_challenge);
527 
528 #if 0 /* encoders not used! */
529 MAKE_ENCFN(asn1_encode_sequence_of_checksum, seq_of_checksum);
530 static asn1_error_code
531 asn1_encode_sam_challenge_2(asn1buf *buf, const krb5_sam_challenge_2 *val,
532                             unsigned int *retlen)
533 {
534     asn1_setup();
535     if ( (!val) || (!val->sam_cksum) || (!val->sam_cksum[0]))
536         return ASN1_MISSING_FIELD;
537 
538     asn1_addfield(val->sam_cksum, 1, asn1_encode_sequence_of_checksum);
539 
540     {
541         unsigned int length;
542 
543         retval = asn1buf_insert_octetstring(buf, val->sam_challenge_2_body.length,
544                                             (unsigned char *)val->sam_challenge_2_body.data);
545         if (retval) {
546             return retval;
547         }
548         sum += val->sam_challenge_2_body.length;
549         retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0,
550                                 val->sam_challenge_2_body.length, &length);
551         if (retval) {
552             return retval;
553         }
554         sum += length;
555     }
556 
557     asn1_makeseq();
558     asn1_cleanup();
559 }
560 DEFFNXTYPE(sam_challenge_2, krb5_sam_challenge_2, asn1_encode_sam_challenge_2);
561 
562 static const struct field_info sam_challenge_2_body_fields[] = {
563     FIELDOF_NORM(krb5_sam_challenge_2_body, int32, sam_type, 0),
564     FIELDOF_NORM(krb5_sam_challenge_2_body, krb5_flags, sam_flags, 1),
565     FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_type_name, 2, 2),
566     FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_track_id,3, 3),
567     FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_challenge_label,4, 4),
568     FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_challenge,5, 5),
569     FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_response_prompt,6, 6),
570     FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_pk_for_sad,7, 7),
571     FIELDOF_NORM(krb5_sam_challenge_2_body, int32, sam_nonce, 8),
572     FIELDOF_NORM(krb5_sam_challenge_2_body, int32, sam_etype, 9),
573 };
574 static unsigned int optional_sam_challenge_2_body(const void *p)
575 {
576     const krb5_sam_challenge_2_body *val = p;
577     unsigned int optional = 0;
578 
579     if (val->sam_pk_for_sad.length > 0) optional |= (1u << 7);
580     if (val->sam_response_prompt.length > 0) optional |= (1u << 6);
581     if (val->sam_challenge.length > 0) optional |= (1u << 5);
582     if (val->sam_challenge_label.length > 0) optional |= (1u << 4);
583     if (val->sam_track_id.length > 0) optional |= (1u << 3);
584     if (val->sam_type_name.length > 0) optional |= (1u << 2);
585 
586     return optional;
587 }
588 DEFSEQTYPE(sam_challenge_2_body,krb5_sam_challenge_2_body,sam_challenge_2_body_fields,
589            optional_sam_challenge_2_body);
590 #endif
591 
592 static const struct field_info sam_key_fields[] = {
593     FIELDOF_NORM(krb5_sam_key, encryption_key, sam_key, 0),
594 };
595 DEFSEQTYPE(sam_key, krb5_sam_key, sam_key_fields, 0);
596 
597 static const struct field_info enc_sam_response_enc_fields[] = {
598     FIELDOF_NORM(krb5_enc_sam_response_enc, int32, sam_nonce, 0),
599     FIELDOF_NORM(krb5_enc_sam_response_enc, kerberos_time, sam_timestamp, 1),
600     FIELDOF_NORM(krb5_enc_sam_response_enc, int32, sam_usec, 2),
601     FIELDOF_OPT(krb5_enc_sam_response_enc, ostring_data, sam_sad, 3, 3),
602 };
603 static unsigned int optional_enc_sam_response_enc(const void *p)
604 {
605     const krb5_enc_sam_response_enc *val = p;
606     unsigned int optional = 0;
607 
608     if (val->sam_sad.length > 0) optional |= (1u << 3);
609 
610     return optional;
611 }
612 DEFSEQTYPE(enc_sam_response_enc, krb5_enc_sam_response_enc,
613            enc_sam_response_enc_fields, optional_enc_sam_response_enc);
614 
615 static const struct field_info enc_sam_response_enc_2_fields[] = {
616     FIELDOF_NORM(krb5_enc_sam_response_enc_2, int32, sam_nonce, 0),
617     FIELDOF_OPT(krb5_enc_sam_response_enc_2, ostring_data, sam_sad, 1, 1),
618 };
619 static unsigned int optional_enc_sam_response_enc_2(const void *p)
620 {
621     const krb5_enc_sam_response_enc_2 *val = p;
622     unsigned int optional = 0;
623 
624     if (val->sam_sad.length > 0) optional |= (1u << 1);
625 
626     return optional;
627 }
628 DEFSEQTYPE(enc_sam_response_enc_2, krb5_enc_sam_response_enc_2,
629            enc_sam_response_enc_2_fields, optional_enc_sam_response_enc_2);
630 
631 static const struct field_info sam_response_fields[] = {
632     FIELDOF_NORM(krb5_sam_response, int32, sam_type, 0),
633     FIELDOF_NORM(krb5_sam_response, krb5_flags, sam_flags, 1),
634     FIELDOF_OPT(krb5_sam_response, ostring_data, sam_track_id, 2, 2),
635     FIELDOF_OPT(krb5_sam_response, encrypted_data, sam_enc_key, 3, 3),
636     FIELDOF_NORM(krb5_sam_response, encrypted_data, sam_enc_nonce_or_ts, 4),
637     FIELDOF_OPT(krb5_sam_response, int32, sam_nonce, 5, 5),
638     FIELDOF_OPT(krb5_sam_response, kerberos_time, sam_patimestamp, 6, 6),
639 };
640 static unsigned int optional_sam_response(const void *p)
641 {
642     const krb5_sam_response *val = p;
643     unsigned int optional = 0;
644 
645     if (val->sam_patimestamp)
646         optional |= (1u << 6);
647     if (val->sam_nonce)
648         optional |= (1u << 5);
649     if (val->sam_enc_key.ciphertext.length)
650         optional |= (1u << 3);
651     if (val->sam_track_id.length > 0) optional |= (1u << 2);
652 
653     return optional;
654 }
655 DEFSEQTYPE(sam_response, krb5_sam_response, sam_response_fields,
656            optional_sam_response);
657 
658 static const struct field_info sam_response_2_fields[] = {
659     FIELDOF_NORM(krb5_sam_response_2, int32, sam_type, 0),
660     FIELDOF_NORM(krb5_sam_response_2, krb5_flags, sam_flags, 1),
661     FIELDOF_OPT(krb5_sam_response_2, ostring_data, sam_track_id, 2, 2),
662     FIELDOF_NORM(krb5_sam_response_2, encrypted_data, sam_enc_nonce_or_sad, 3),
663     FIELDOF_NORM(krb5_sam_response_2, int32, sam_nonce, 4),
664 };
665 static unsigned int optional_sam_response_2(const void *p)
666 {
667     const krb5_sam_response_2 *val = p;
668     unsigned int optional = 0;
669 
670     if (val->sam_track_id.length > 0) optional |= (1u << 2);
671 
672     return optional;
673 }
674 DEFSEQTYPE(sam_response_2, krb5_sam_response_2, sam_response_2_fields,
675            optional_sam_response_2);
676 
677 static const struct field_info predicted_sam_response_fields[] = {
678     FIELDOF_NORM(krb5_predicted_sam_response, encryption_key, sam_key, 0),
679     FIELDOF_NORM(krb5_predicted_sam_response, krb5_flags, sam_flags, 1),
680     FIELDOF_NORM(krb5_predicted_sam_response, kerberos_time, stime, 2),
681     FIELDOF_NORM(krb5_predicted_sam_response, int32, susec, 3),
682     FIELDOF_NORM(krb5_predicted_sam_response, realm_of_principal, client, 4),
683     FIELDOF_NORM(krb5_predicted_sam_response, principal, client, 5),
684     FIELDOF_OPT(krb5_predicted_sam_response, ostring_data, msd, 6, 6),
685 };
686 static unsigned int optional_predicted_sam_response(const void *p)
687 {
688     const krb5_predicted_sam_response *val = p;
689     unsigned int optional = 0;
690 
691     if (val->msd.length > 0) optional |= (1u << 6);
692 
693     return optional;
694 }
695 DEFSEQTYPE(predicted_sam_response, krb5_predicted_sam_response,
696            predicted_sam_response_fields,
697            optional_predicted_sam_response);
698 
699 static const struct field_info krb5_authenticator_fields[] = {
700     /* Authenticator ::= [APPLICATION 2] SEQUENCE */
701     /* authenticator-vno[0]     INTEGER */
702     FIELD_INT_IMM(KVNO, 0),
703     /* crealm[1]                        Realm */
704     FIELDOF_NORM(krb5_authenticator, realm_of_principal, client, 1),
705     /* cname[2]                 PrincipalName */
706     FIELDOF_NORM(krb5_authenticator, principal, client, 2),
707     /* cksum[3]                 Checksum OPTIONAL */
708     FIELDOF_OPT(krb5_authenticator, checksum_ptr, checksum, 3, 3),
709     /* cusec[4]                 INTEGER */
710     FIELDOF_NORM(krb5_authenticator, int32, cusec, 4),
711     /* ctime[5]                 KerberosTime */
712     FIELDOF_NORM(krb5_authenticator, kerberos_time, ctime, 5),
713     /* subkey[6]                        EncryptionKey OPTIONAL */
714     FIELDOF_OPT(krb5_authenticator, ptr_encryption_key, subkey, 6, 6),
715     /* seq-number[7]            INTEGER OPTIONAL */
716     FIELDOF_OPT(krb5_authenticator, uint, seq_number, 7, 7),
717     /* authorization-data[8]    AuthorizationData OPTIONAL */
718     FIELDOF_OPT(krb5_authenticator, auth_data_ptr, authorization_data, 8, 8),
719 };
720 static unsigned int optional_krb5_authenticator(const void *p)
721 {
722     const krb5_authenticator *val = p;
723     unsigned int optional = 0;
724 
725     if (val->authorization_data != NULL && val->authorization_data[0] != NULL)
726         optional |= (1u << 8);
727 
728     if (val->seq_number != 0)
729         optional |= (1u << 7);
730 
731     if (val->subkey != NULL)
732         optional |= (1u << 6);
733 
734     if (val->checksum != NULL)
735         optional |= (1u << 3);
736 
737     return optional;
738 }
739 DEFSEQTYPE(untagged_krb5_authenticator, krb5_authenticator, krb5_authenticator_fields,
740            optional_krb5_authenticator);
741 DEFAPPTAGGEDTYPE(krb5_authenticator, 2, untagged_krb5_authenticator);
742 
743 static const struct field_info enc_tkt_part_fields[] = {
744     /* EncTicketPart ::= [APPLICATION 3] SEQUENCE */
745     /* flags[0]                 TicketFlags */
746     FIELDOF_NORM(krb5_enc_tkt_part, krb5_flags, flags, 0),
747     /* key[1]                   EncryptionKey */
748     FIELDOF_NORM(krb5_enc_tkt_part, ptr_encryption_key, session, 1),
749     /* crealm[2]                        Realm */
750     FIELDOF_NORM(krb5_enc_tkt_part, realm_of_principal, client, 2),
751     /* cname[3]                 PrincipalName */
752     FIELDOF_NORM(krb5_enc_tkt_part, principal, client, 3),
753     /* transited[4]             TransitedEncoding */
754     FIELDOF_NORM(krb5_enc_tkt_part, transited, transited, 4),
755     /* authtime[5]              KerberosTime */
756     FIELDOF_NORM(krb5_enc_tkt_part, kerberos_time, times.authtime, 5),
757     /* starttime[6]             KerberosTime OPTIONAL */
758     FIELDOF_OPT(krb5_enc_tkt_part, kerberos_time, times.starttime, 6, 6),
759     /* endtime[7]                       KerberosTime */
760     FIELDOF_NORM(krb5_enc_tkt_part, kerberos_time, times.endtime, 7),
761     /* renew-till[8]            KerberosTime OPTIONAL */
762     FIELDOF_OPT(krb5_enc_tkt_part, kerberos_time, times.renew_till, 8, 8),
763     /* caddr[9]                 HostAddresses OPTIONAL */
764     FIELDOF_OPT(krb5_enc_tkt_part, ptr_seqof_host_addresses, caddrs, 9, 9),
765     /* authorization-data[10]   AuthorizationData OPTIONAL */
766     FIELDOF_OPT(krb5_enc_tkt_part, auth_data_ptr, authorization_data, 10, 10),
767 };
768 static unsigned int optional_enc_tkt_part(const void *p)
769 {
770     const krb5_enc_tkt_part *val = p;
771     unsigned int optional = 0;
772 
773     if (val->authorization_data != NULL && val->authorization_data[0] != NULL)
774         optional |= (1u << 10);
775     if (val->caddrs != NULL && val->caddrs[0] != NULL)
776         optional |= (1u << 9);
777     if (val->times.renew_till)
778         optional |= (1u << 8);
779     if (val->times.starttime)
780         optional |= (1u << 6);
781 
782     return optional;
783 }
784 DEFSEQTYPE(untagged_enc_tkt_part, krb5_enc_tkt_part, enc_tkt_part_fields,
785            optional_enc_tkt_part);
786 DEFAPPTAGGEDTYPE(enc_tkt_part, 3, untagged_enc_tkt_part);
787 
788 DEFAPPTAGGEDTYPE(enc_tgs_rep_part, 26, enc_kdc_rep_part);
789 
790 static const struct field_info as_rep_fields[] = {
791     /* AS-REP ::= [APPLICATION 11] KDC-REP */
792     /* But KDC-REP needs to know what type it's being encapsulated
793        in, so expand each version.  */
794     FIELD_INT_IMM(KVNO, 0),
795     FIELD_INT_IMM(KRB5_AS_REP, 1),
796     FIELDOF_OPT(krb5_kdc_rep, ptr_seqof_pa_data, padata, 2, 2),
797     FIELDOF_NORM(krb5_kdc_rep, realm_of_principal, client, 3),
798     FIELDOF_NORM(krb5_kdc_rep, principal, client, 4),
799     FIELDOF_NORM(krb5_kdc_rep, ticket_ptr, ticket, 5),
800     FIELDOF_NORM(krb5_kdc_rep, encrypted_data, enc_part, 6),
801 };
802 static unsigned int optional_as_rep(const void *p)
803 {
804     const krb5_kdc_rep *val = p;
805     unsigned int optional = 0;
806 
807     if (val->padata != NULL && val->padata[0] != NULL)
808         optional |= (1u << 2);
809 
810     return optional;
811 }
812 DEFSEQTYPE(untagged_as_rep, krb5_kdc_rep, as_rep_fields, optional_as_rep);
813 DEFAPPTAGGEDTYPE(as_rep, 11, untagged_as_rep);
814 
815 static const struct field_info tgs_rep_fields[] = {
816     /* TGS-REP ::= [APPLICATION 13] KDC-REP */
817     /* But KDC-REP needs to know what type it's being encapsulated
818        in, so expand each version.  */
819     FIELD_INT_IMM(KVNO, 0),
820     FIELD_INT_IMM(KRB5_TGS_REP, 1),
821     FIELDOF_OPT(krb5_kdc_rep, ptr_seqof_pa_data, padata, 2, 2),
822     FIELDOF_NORM(krb5_kdc_rep, realm_of_principal, client, 3),
823     FIELDOF_NORM(krb5_kdc_rep, principal, client, 4),
824     FIELDOF_NORM(krb5_kdc_rep, ticket_ptr, ticket, 5),
825     FIELDOF_NORM(krb5_kdc_rep, encrypted_data, enc_part, 6),
826 };
827 static unsigned int optional_tgs_rep(const void *p)
828 {
829     const krb5_kdc_rep *val = p;
830     unsigned int optional = 0;
831 
832     if (val->padata != NULL && val->padata[0] != NULL)
833         optional |= (1u << 2);
834 
835     return optional;
836 }
837 DEFSEQTYPE(untagged_tgs_rep, krb5_kdc_rep, tgs_rep_fields, optional_tgs_rep);
838 DEFAPPTAGGEDTYPE(tgs_rep, 13, untagged_tgs_rep);
839 
840 static const struct field_info ap_req_fields[] = {
841     /* AP-REQ ::=       [APPLICATION 14] SEQUENCE */
842     /* pvno[0]          INTEGER */
843     FIELD_INT_IMM(KVNO, 0),
844     /* msg-type[1]      INTEGER */
845     FIELD_INT_IMM(ASN1_KRB_AP_REQ, 1),
846     /* ap-options[2]    APOptions */
847     FIELDOF_NORM(krb5_ap_req, krb5_flags, ap_options, 2),
848     /* ticket[3]                Ticket */
849     FIELDOF_NORM(krb5_ap_req, ticket_ptr, ticket, 3),
850     /* authenticator[4] EncryptedData */
851     FIELDOF_NORM(krb5_ap_req, encrypted_data, authenticator, 4),
852 };
853 DEFSEQTYPE(untagged_ap_req, krb5_ap_req, ap_req_fields, 0);
854 DEFAPPTAGGEDTYPE(ap_req, 14, untagged_ap_req);
855 
856 static const struct field_info ap_rep_fields[] = {
857     /* AP-REP ::=       [APPLICATION 15] SEQUENCE */
858     /* pvno[0]          INTEGER */
859     FIELD_INT_IMM(KVNO, 0),
860     /* msg-type[1]      INTEGER */
861     FIELD_INT_IMM(ASN1_KRB_AP_REP, 1),
862     /* enc-part[2]      EncryptedData */
863     FIELDOF_NORM(krb5_ap_rep, encrypted_data, enc_part, 2),
864 };
865 DEFSEQTYPE(untagged_ap_rep, krb5_ap_rep, ap_rep_fields, 0);
866 DEFAPPTAGGEDTYPE(ap_rep, 15, untagged_ap_rep);
867 
868 static const struct field_info ap_rep_enc_part_fields[] = {
869     /* EncAPRepPart ::= [APPLICATION 27] SEQUENCE */
870     /* ctime[0]         KerberosTime */
871     FIELDOF_NORM(krb5_ap_rep_enc_part, kerberos_time, ctime, 0),
872     /* cusec[1]         INTEGER */
873     FIELDOF_NORM(krb5_ap_rep_enc_part, int32, cusec, 1),
874     /* subkey[2]                EncryptionKey OPTIONAL */
875     FIELDOF_OPT(krb5_ap_rep_enc_part, ptr_encryption_key, subkey, 2, 2),
876     /* seq-number[3]    INTEGER OPTIONAL */
877     FIELDOF_OPT(krb5_ap_rep_enc_part, uint, seq_number, 3, 3),
878 };
879 static unsigned int optional_ap_rep_enc_part(const void *p)
880 {
881     const krb5_ap_rep_enc_part *val = p;
882     unsigned int optional = 0;
883 
884     if (val->seq_number)
885         optional |= (1u << 3);
886     if (val->subkey != NULL)
887         optional |= (1u << 2);
888 
889     return optional;
890 }
891 DEFSEQTYPE(untagged_ap_rep_enc_part, krb5_ap_rep_enc_part,
892            ap_rep_enc_part_fields, optional_ap_rep_enc_part);
893 DEFAPPTAGGEDTYPE(ap_rep_enc_part, 27, untagged_ap_rep_enc_part);
894 
895 static const struct field_info as_req_fields[] = {
896     /* AS-REQ ::= [APPLICATION 10] KDC-REQ */
897     FIELD_INT_IMM(KVNO, 1),
898     FIELD_INT_IMM(KRB5_AS_REQ, 2),
899     FIELDOF_OPT(krb5_kdc_req, ptr_seqof_pa_data, padata, 3, 3),
900     FIELDOF_ENCODEAS(krb5_kdc_req, kdc_req_body, 4),
901 };
902 static unsigned int optional_as_req(const void *p)
903 {
904     const krb5_kdc_req *val = p;
905     unsigned int optional = 0;
906 
907     if (val->padata != NULL && val->padata[0] != NULL)
908         optional |= (1u << 3);
909 
910     return optional;
911 }
912 DEFSEQTYPE(untagged_as_req, krb5_kdc_req, as_req_fields, optional_as_req);
913 DEFAPPTAGGEDTYPE(as_req, 10, untagged_as_req);
914 
915 static const struct field_info tgs_req_fields[] = {
916     /* TGS-REQ ::= [APPLICATION 12] KDC-REQ */
917     FIELD_INT_IMM(KVNO, 1),
918     FIELD_INT_IMM(KRB5_TGS_REQ, 2),
919     FIELDOF_OPT(krb5_kdc_req, ptr_seqof_pa_data, padata, 3, 3),
920     FIELDOF_ENCODEAS(krb5_kdc_req, kdc_req_body, 4),
921 };
922 static unsigned int optional_tgs_req(const void *p)
923 {
924     const krb5_kdc_req *val = p;
925     unsigned int optional = 0;
926 
927     if (val->padata != NULL && val->padata[0] != NULL)
928         optional |= (1u << 3);
929 
930     return optional;
931 }
932 DEFSEQTYPE(untagged_tgs_req, krb5_kdc_req, tgs_req_fields,
933            optional_tgs_req);
934 DEFAPPTAGGEDTYPE(tgs_req, 12, untagged_tgs_req);
935 
936 static const struct field_info krb5_safe_fields[] = {
937     FIELD_INT_IMM(KVNO, 0),
938     FIELD_INT_IMM(ASN1_KRB_SAFE,1),
939     FIELD_SELF(krb_safe_body, 2),
940     FIELDOF_NORM(krb5_safe, checksum_ptr, checksum, 3),
941 };
942 DEFSEQTYPE(untagged_krb5_safe, krb5_safe, krb5_safe_fields, 0);
943 DEFAPPTAGGEDTYPE(krb5_safe, 20, untagged_krb5_safe);
944 
945 DEFPTRTYPE(krb_saved_safe_body_ptr, opaque_data);
946 DEFFIELDTYPE(krb5_safe_checksum_only, krb5_safe,
947              FIELDOF_NORM(krb5_safe, checksum_ptr, checksum, -1));
948 DEFPTRTYPE(krb5_safe_checksum_only_ptr, krb5_safe_checksum_only);
949 static const struct field_info krb5_safe_with_body_fields[] = {
950     FIELD_INT_IMM(KVNO, 0),
951     FIELD_INT_IMM(ASN1_KRB_SAFE,1),
952     FIELDOF_NORM(struct krb5_safe_with_body, krb_saved_safe_body_ptr, body, 2),
953     FIELDOF_NORM(struct krb5_safe_with_body, krb5_safe_checksum_only_ptr, safe, 3),
954 };
955 DEFSEQTYPE(untagged_krb5_safe_with_body, struct krb5_safe_with_body,
956            krb5_safe_with_body_fields, 0);
957 DEFAPPTAGGEDTYPE(krb5_safe_with_body, 20, untagged_krb5_safe_with_body);
958 
959 static const struct field_info priv_fields[] = {
960     FIELD_INT_IMM(KVNO, 0),
961     FIELD_INT_IMM(ASN1_KRB_PRIV, 1),
962     FIELDOF_NORM(krb5_priv, encrypted_data, enc_part, 3),
963 };
964 DEFSEQTYPE(untagged_priv, krb5_priv, priv_fields, 0);
965 DEFAPPTAGGEDTYPE(krb5_priv, 21, untagged_priv);
966 
967 static const struct field_info priv_enc_part_fields[] = {
968     FIELDOF_NORM(krb5_priv_enc_part, ostring_data, user_data, 0),
969     FIELDOF_OPT(krb5_priv_enc_part, kerberos_time, timestamp, 1, 1),
970     FIELDOF_OPT(krb5_priv_enc_part, int32, usec, 2, 2),
971     FIELDOF_OPT(krb5_priv_enc_part, uint, seq_number, 3, 3),
972     FIELDOF_NORM(krb5_priv_enc_part, address_ptr, s_address, 4),
973     FIELDOF_OPT(krb5_priv_enc_part, address_ptr, r_address, 5, 5),
974 };
975 static unsigned int optional_priv_enc_part(const void *p)
976 {
977     const krb5_priv_enc_part *val = p;
978     unsigned int optional = 0;
979 
980     if (val->timestamp) {
981         optional |= (1u << 2);
982         optional |= (1u << 1);
983     }
984     if (val->seq_number)
985         optional |= (1u << 3);
986     if (val->r_address)
987         optional |= (1u << 5);
988 
989     return optional;
990 }
991 DEFSEQTYPE(untagged_priv_enc_part, krb5_priv_enc_part, priv_enc_part_fields,
992            optional_priv_enc_part);
993 DEFAPPTAGGEDTYPE(priv_enc_part, 28, untagged_priv_enc_part);
994 
995 static const struct field_info cred_fields[] = {
996     /* KRB-CRED ::= [APPLICATION 22] SEQUENCE */
997     /* pvno[0]          INTEGER */
998     FIELD_INT_IMM(KVNO, 0),
999     /* msg-type[1]      INTEGER, -- KRB_CRED */
1000     FIELD_INT_IMM(ASN1_KRB_CRED, 1),
1001     /* tickets[2]       SEQUENCE OF Ticket */
1002     FIELDOF_NORM(krb5_cred, ptr_seqof_ticket, tickets, 2),
1003     /* enc-part[3]      EncryptedData */
1004     FIELDOF_NORM(krb5_cred, encrypted_data, enc_part, 3),
1005 };
1006 DEFSEQTYPE(untagged_cred, krb5_cred, cred_fields, 0);
1007 DEFAPPTAGGEDTYPE(krb5_cred, 22, untagged_cred);
1008 
1009 static const struct field_info enc_cred_part_fields[] = {
1010     /* EncKrbCredPart ::= [APPLICATION 29] SEQUENCE */
1011     /* ticket-info[0]   SEQUENCE OF KrbCredInfo */
1012     FIELDOF_NORM(krb5_cred_enc_part, ptrseqof_cred_info, ticket_info, 0),
1013     /* nonce[1]         INTEGER OPTIONAL */
1014     FIELDOF_OPT(krb5_cred_enc_part, int32, nonce, 1, 1),
1015     /* timestamp[2]     KerberosTime OPTIONAL */
1016     FIELDOF_OPT(krb5_cred_enc_part, kerberos_time, timestamp, 2, 2),
1017     /* usec[3]          INTEGER OPTIONAL */
1018     FIELDOF_OPT(krb5_cred_enc_part, int32, usec, 3, 3),
1019     /* s-address[4]     HostAddress OPTIONAL */
1020     FIELDOF_OPT(krb5_cred_enc_part, address_ptr, s_address, 4, 4),
1021     /* r-address[5]     HostAddress OPTIONAL */
1022     FIELDOF_OPT(krb5_cred_enc_part, address_ptr, r_address, 5, 5),
1023 };
1024 static unsigned int optional_enc_cred_part(const void *p)
1025 {
1026     const krb5_cred_enc_part *val = p;
1027     unsigned int optional = 0;
1028 
1029     if (val->r_address != NULL)
1030         optional |= (1u << 5);
1031 
1032     if (val->s_address != NULL)
1033         optional |= (1u << 4);
1034 
1035     if (val->timestamp) {
1036         optional |= (1u << 2);
1037         optional |= (1u << 3);
1038     }
1039 
1040     if (val->nonce)
1041         optional |= (1u << 1);
1042 
1043     return optional;
1044 }
1045 DEFSEQTYPE(untagged_enc_cred_part, krb5_cred_enc_part, enc_cred_part_fields,
1046            optional_enc_cred_part);
1047 DEFAPPTAGGEDTYPE(enc_cred_part, 29, untagged_enc_cred_part);
1048 
1049 static const struct field_info error_fields[] = {
1050     /* KRB-ERROR ::= [APPLICATION 30] SEQUENCE */
1051     /* pvno[0]          INTEGER */
1052     FIELD_INT_IMM(KVNO, 0),
1053     /* msg-type[1]      INTEGER */
1054     FIELD_INT_IMM(ASN1_KRB_ERROR, 1),
1055     /* ctime[2]         KerberosTime OPTIONAL */
1056     FIELDOF_OPT(krb5_error, kerberos_time, ctime, 2, 2),
1057     /* cusec[3]         INTEGER OPTIONAL */
1058     FIELDOF_OPT(krb5_error, int32, cusec, 3, 3),
1059     /* stime[4]         KerberosTime */
1060     FIELDOF_NORM(krb5_error, kerberos_time, stime, 4),
1061     /* susec[5]         INTEGER */
1062     FIELDOF_NORM(krb5_error, int32, susec, 5),
1063     /* error-code[6]    INTEGER */
1064     FIELDOF_NORM(krb5_error, ui_4, error, 6),
1065     /* crealm[7]        Realm OPTIONAL */
1066     FIELDOF_OPT(krb5_error, realm_of_principal, client, 7, 7),
1067     /* cname[8]         PrincipalName OPTIONAL */
1068     FIELDOF_OPT(krb5_error, principal, client, 8, 8),
1069     /* realm[9]         Realm -- Correct realm */
1070     FIELDOF_NORM(krb5_error, realm_of_principal, server, 9),
1071     /* sname[10]        PrincipalName -- Correct name */
1072     FIELDOF_NORM(krb5_error, principal, server, 10),
1073     /* e-text[11]       GeneralString OPTIONAL */
1074     FIELDOF_OPT(krb5_error, gstring_data, text, 11, 11),
1075     /* e-data[12]       OCTET STRING OPTIONAL */
1076     FIELDOF_OPT(krb5_error, ostring_data, e_data, 12, 12),
1077 };
1078 static unsigned int optional_error(const void *p)
1079 {
1080     const krb5_error *val = p;
1081     unsigned int optional = 0;
1082 
1083     if (val->ctime)
1084         optional |= (1u << 2);
1085     if (val->cusec)
1086         optional |= (1u << 3);
1087     if (val->client) {
1088         optional |= (1u << 7);
1089         optional |= (1u << 8);
1090     }
1091     if (val->text.data != NULL && val->text.length > 0)
1092         optional |= (1u << 11);
1093     if (val->e_data.data != NULL && val->e_data.length > 0)
1094         optional |= (1u << 12);
1095 
1096     return optional;
1097 }
1098 DEFSEQTYPE(untagged_krb5_error, krb5_error, error_fields, optional_error);
1099 DEFAPPTAGGEDTYPE(krb5_error, 30, untagged_krb5_error);
1100 
1101 static const struct field_info alt_method_fields[] = {
1102     FIELDOF_NORM(krb5_alt_method, int32, method, 0),
1103     FIELDOF_OPTSTRING(krb5_alt_method, octetstring, data, length, 1, 1),
1104 };
1105 static unsigned int
1106 optional_alt_method(const void *p)
1107 {
1108     const krb5_alt_method *a = p;
1109     unsigned int optional = 0;
1110 
1111     if (a->data != NULL && a->length > 0)
1112         optional |= (1u << 1);
1113 
1114     return optional;
1115 }
1116 DEFSEQTYPE(alt_method, krb5_alt_method, alt_method_fields, optional_alt_method);
1117 
1118 static const struct field_info pa_enc_ts_fields[] = {
1119     FIELDOF_NORM(krb5_pa_enc_ts, kerberos_time, patimestamp, 0),
1120     FIELDOF_OPT(krb5_pa_enc_ts, int32, pausec, 1, 1),
1121 };
1122 static unsigned int
1123 optional_pa_enc_ts(const void *p)
1124 {
1125     const krb5_pa_enc_ts *val = p;
1126     unsigned int optional = 0;
1127 
1128     if (val->pausec)
1129         optional |= (1u << 1);
1130 
1131     return optional;
1132 }
1133 DEFSEQTYPE(pa_enc_ts, krb5_pa_enc_ts, pa_enc_ts_fields, optional_pa_enc_ts);
1134 
1135 static const struct field_info pwd_data_fields[] = {
1136     FIELDOF_NORM(krb5_pwd_data, int32, sequence_count, 0),
1137     FIELDOF_NORM(krb5_pwd_data, ptr_seqof_passwdsequence, element, 1),
1138 };
1139 DEFSEQTYPE(pwd_data, krb5_pwd_data, pwd_data_fields, 0);
1140 
1141 static const struct field_info setpw_req_fields[] = {
1142     FIELDOF_NORM(struct krb5_setpw_req, ostring_data, password, 0),
1143     FIELDOF_NORM(struct krb5_setpw_req, principal, target, 1),
1144     FIELDOF_NORM(struct krb5_setpw_req, realm_of_principal, target, 2),
1145 };
1146 
1147 DEFSEQTYPE(setpw_req, struct krb5_setpw_req, setpw_req_fields, 0);
1148 
1149 /* [MS-SFU] Section 2.2.1. */
1150 static const struct field_info pa_for_user_fields[] = {
1151     FIELDOF_NORM(krb5_pa_for_user, principal, user, 0),
1152     FIELDOF_NORM(krb5_pa_for_user, realm_of_principal, user, 1),
1153     FIELDOF_NORM(krb5_pa_for_user, checksum, cksum, 2),
1154     FIELDOF_NORM(krb5_pa_for_user, gstring_data, auth_package, 3),
1155 };
1156 
1157 DEFSEQTYPE(pa_for_user, krb5_pa_for_user, pa_for_user_fields, 0);
1158 
1159 /* draft-ietf-krb-wg-kerberos-referrals Appendix A. */
1160 static const struct field_info pa_svr_referral_data_fields[] = {
1161     FIELDOF_NORM(krb5_pa_svr_referral_data, realm_of_principal, principal, 0),
1162     FIELDOF_OPT(krb5_pa_svr_referral_data, principal, principal, 1, 1),
1163 };
1164 
1165 DEFSEQTYPE(pa_svr_referral_data, krb5_pa_svr_referral_data, pa_svr_referral_data_fields, 0);
1166 
1167 /* draft-ietf-krb-wg-kerberos-referrals Section 8. */
1168 static const struct field_info pa_server_referral_data_fields[] = {
1169     FIELDOF_OPT(krb5_pa_server_referral_data, gstring_data_ptr, referred_realm, 0, 0),
1170     FIELDOF_OPT(krb5_pa_server_referral_data, principal, true_principal_name, 1, 1),
1171     FIELDOF_OPT(krb5_pa_server_referral_data, principal, requested_principal_name, 2, 2),
1172     FIELDOF_OPT(krb5_pa_server_referral_data, kerberos_time, referral_valid_until, 3, 3),
1173     FIELDOF_NORM(krb5_pa_server_referral_data, checksum, rep_cksum, 4),
1174 };
1175 
1176 DEFSEQTYPE(pa_server_referral_data, krb5_pa_server_referral_data, pa_server_referral_data_fields, 0);
1177 
1178 #if 0
1179 /* draft-brezak-win2k-krb-authz Section 6. */
1180 static const struct field_info pa_pac_request_fields[] = {
1181     FIELDOF_NORM(krb5_pa_pac_req, boolean, include_pac, 0),
1182 };
1183 
1184 DEFSEQTYPE(pa_pac_request, krb5_pa_pac_req, pa_pac_request_fields, 0);
1185 #endif
1186 
1187 /* RFC 4537 */
1188 DEFFIELDTYPE(etype_list, krb5_etype_list,
1189              FIELDOF_SEQOF_INT32(krb5_etype_list, int32_ptr, etypes, length, -1));
1190 
1191 /* draft-ietf-krb-wg-preauth-framework-09 */
1192 static const struct field_info fast_armor_fields[] = {
1193     FIELDOF_NORM(krb5_fast_armor, int32, armor_type, 0),
1194     FIELDOF_NORM( krb5_fast_armor, ostring_data, armor_value, 1),
1195 };
1196 
1197 DEFSEQTYPE( fast_armor, krb5_fast_armor, fast_armor_fields, 0);
1198 DEFPTRTYPE( ptr_fast_armor, fast_armor);
1199 
1200 static const struct field_info fast_armored_req_fields[] = {
1201     FIELDOF_OPT( krb5_fast_armored_req, ptr_fast_armor, armor, 0, 0),
1202     FIELDOF_NORM( krb5_fast_armored_req, checksum, req_checksum, 1),
1203     FIELDOF_NORM( krb5_fast_armored_req, encrypted_data, enc_part, 2),
1204 };
1205 
1206 static unsigned int fast_armored_req_optional (const void *p) {
1207     const krb5_fast_armored_req *val = p;
1208     unsigned int optional = 0;
1209     if (val->armor)
1210         optional |= (1u)<<0;
1211     return optional;
1212 }
1213 
1214 DEFSEQTYPE( fast_armored_req, krb5_fast_armored_req, fast_armored_req_fields, fast_armored_req_optional);
1215 DEFFIELDTYPE( pa_fx_fast_request, krb5_fast_armored_req,
1216               FIELDOF_ENCODEAS( krb5_fast_armored_req, fast_armored_req, 0));
1217 
1218 DEFFIELDTYPE(fast_req_padata, krb5_kdc_req,
1219              FIELDOF_NORM(krb5_kdc_req, ptr_seqof_pa_data, padata, -1));
1220 DEFPTRTYPE(ptr_fast_req_padata, fast_req_padata);
1221 
1222 static const struct field_info fast_req_fields[] = {
1223     FIELDOF_NORM(krb5_fast_req, krb5_flags, fast_options, 0),
1224     FIELDOF_NORM( krb5_fast_req, ptr_fast_req_padata, req_body, 1),
1225     FIELDOF_NORM( krb5_fast_req, ptr_kdc_req_body, req_body, 2),
1226 };
1227 
1228 DEFSEQTYPE(fast_req, krb5_fast_req, fast_req_fields, 0);
1229 
1230 
1231 static const struct field_info fast_finished_fields[] = {
1232     FIELDOF_NORM( krb5_fast_finished, kerberos_time, timestamp, 0),
1233     FIELDOF_NORM( krb5_fast_finished, int32, usec, 1),
1234     FIELDOF_NORM( krb5_fast_finished, realm_of_principal, client, 2),
1235     FIELDOF_NORM(krb5_fast_finished, principal, client, 3),
1236     FIELDOF_NORM( krb5_fast_finished, checksum, ticket_checksum, 4),
1237 };
1238 
1239 DEFSEQTYPE( fast_finished, krb5_fast_finished, fast_finished_fields, 0);
1240 
1241 DEFPTRTYPE( ptr_fast_finished, fast_finished);
1242 
1243 static const struct field_info fast_response_fields[] = {
1244     FIELDOF_NORM(krb5_fast_response, ptr_seqof_pa_data, padata, 0),
1245     FIELDOF_OPT( krb5_fast_response, ptr_encryption_key, strengthen_key, 1, 1),
1246     FIELDOF_OPT( krb5_fast_response, ptr_fast_finished, finished, 2, 2),
1247     FIELDOF_NORM(krb5_fast_response, int32, nonce, 3),
1248 };
1249 
1250 static unsigned int fast_response_optional (const void *p)
1251 {
1252     unsigned int optional = 0;
1253     const krb5_fast_response *val = p;
1254     if (val->strengthen_key)
1255         optional |= (1u <<1);
1256     if (val->finished)
1257         optional |= (1u<<2);
1258     return optional;
1259 }
1260 DEFSEQTYPE( fast_response, krb5_fast_response, fast_response_fields, fast_response_optional);
1261 
1262 static const struct field_info fast_rep_fields[] = {
1263   FIELDOF_ENCODEAS(krb5_enc_data, encrypted_data, 0),
1264 };
1265 DEFSEQTYPE(fast_rep, krb5_enc_data, fast_rep_fields, 0);
1266 
1267 DEFFIELDTYPE(pa_fx_fast_reply, krb5_enc_data,
1268              FIELDOF_ENCODEAS(krb5_enc_data, fast_rep, 0));
1269 
1270 
1271 
1272 
1273 /* Exported complete encoders -- these produce a krb5_data with
1274    the encoding in the correct byte order.  */
1275 
1276 MAKE_FULL_ENCODER(encode_krb5_authenticator, krb5_authenticator);
1277 MAKE_FULL_ENCODER(encode_krb5_ticket, ticket);
1278 MAKE_FULL_ENCODER(encode_krb5_encryption_key, encryption_key);
1279 MAKE_FULL_ENCODER(encode_krb5_enc_tkt_part, enc_tkt_part);
1280 /* XXX We currently (for backwards compatibility) encode both
1281    EncASRepPart and EncTGSRepPart with application tag 26.  */
1282 MAKE_FULL_ENCODER(encode_krb5_enc_kdc_rep_part, enc_tgs_rep_part);
1283 MAKE_FULL_ENCODER(encode_krb5_as_rep, as_rep);
1284 MAKE_FULL_ENCODER(encode_krb5_tgs_rep, tgs_rep);
1285 MAKE_FULL_ENCODER(encode_krb5_ap_req, ap_req);
1286 MAKE_FULL_ENCODER(encode_krb5_ap_rep, ap_rep);
1287 MAKE_FULL_ENCODER(encode_krb5_ap_rep_enc_part, ap_rep_enc_part);
1288 MAKE_FULL_ENCODER(encode_krb5_as_req, as_req);
1289 MAKE_FULL_ENCODER(encode_krb5_tgs_req, tgs_req);
1290 MAKE_FULL_ENCODER(encode_krb5_kdc_req_body, kdc_req_body);
1291 MAKE_FULL_ENCODER(encode_krb5_safe, krb5_safe);
1292 
1293 /*
1294  * encode_krb5_safe_with_body
1295  *
1296  * Like encode_krb5_safe(), except takes a saved KRB-SAFE-BODY
1297  * encoding to avoid problems with re-encoding.
1298  */
1299 MAKE_FULL_ENCODER(encode_krb5_safe_with_body, krb5_safe_with_body);
1300 
1301 MAKE_FULL_ENCODER(encode_krb5_priv, krb5_priv);
1302 MAKE_FULL_ENCODER(encode_krb5_enc_priv_part, priv_enc_part);
1303 MAKE_FULL_ENCODER(encode_krb5_cred, krb5_cred);
1304 MAKE_FULL_ENCODER(encode_krb5_enc_cred_part, enc_cred_part);
1305 MAKE_FULL_ENCODER(encode_krb5_error, krb5_error);
1306 MAKE_FULL_ENCODER(encode_krb5_authdata, auth_data);
1307 MAKE_FULL_ENCODER(encode_krb5_authdata_elt, authdata_elt);
1308 MAKE_FULL_ENCODER(encode_krb5_alt_method, alt_method);
1309 MAKE_FULL_ENCODER(encode_krb5_etype_info, etype_info);
1310 MAKE_FULL_ENCODER(encode_krb5_etype_info2, etype_info2);
1311 MAKE_FULL_ENCODER(encode_krb5_enc_data, encrypted_data);
1312 MAKE_FULL_ENCODER(encode_krb5_pa_enc_ts, pa_enc_ts);
1313 /* Sandia Additions */
1314 MAKE_FULL_ENCODER(encode_krb5_pwd_sequence, passwdsequence);
1315 MAKE_FULL_ENCODER(encode_krb5_pwd_data, pwd_data);
1316 MAKE_FULL_ENCODER(encode_krb5_padata_sequence, seq_of_pa_data);
1317 /* sam preauth additions */
1318 MAKE_FULL_ENCODER(encode_krb5_sam_challenge, sam_challenge);
1319 #if 0 /* encoders not used! */
1320 MAKE_FULL_ENCODER(encode_krb5_sam_challenge_2, sam_challenge_2);
1321 MAKE_FULL_ENCODER(encode_krb5_sam_challenge_2_body,
1322                   sam_challenge_2_body);
1323 #endif
1324 MAKE_FULL_ENCODER(encode_krb5_sam_key, sam_key);
1325 MAKE_FULL_ENCODER(encode_krb5_enc_sam_response_enc,
1326                   enc_sam_response_enc);
1327 MAKE_FULL_ENCODER(encode_krb5_enc_sam_response_enc_2,
1328                   enc_sam_response_enc_2);
1329 MAKE_FULL_ENCODER(encode_krb5_sam_response, sam_response);
1330 MAKE_FULL_ENCODER(encode_krb5_sam_response_2, sam_response_2);
1331 MAKE_FULL_ENCODER(encode_krb5_predicted_sam_response,
1332                   predicted_sam_response);
1333 MAKE_FULL_ENCODER(encode_krb5_setpw_req, setpw_req);
1334 MAKE_FULL_ENCODER(encode_krb5_pa_for_user, pa_for_user);
1335 MAKE_FULL_ENCODER(encode_krb5_pa_svr_referral_data, pa_svr_referral_data);
1336 MAKE_FULL_ENCODER(encode_krb5_pa_server_referral_data, pa_server_referral_data);
1337 MAKE_FULL_ENCODER(encode_krb5_etype_list, etype_list);
1338 
1339 MAKE_FULL_ENCODER(encode_krb5_pa_fx_fast_request, pa_fx_fast_request);
1340 MAKE_FULL_ENCODER( encode_krb5_fast_req, fast_req);
1341 MAKE_FULL_ENCODER( encode_krb5_pa_fx_fast_reply, pa_fx_fast_reply);
1342 MAKE_FULL_ENCODER(encode_krb5_fast_response, fast_response);
1343 
1344 
1345 
1346 
1347 
1348 
1349 /*
1350  * PKINIT
1351  */
1352 
1353 /* This code hasn't been converted to use the above framework yet,
1354    because we currently have no test cases to validate the new
1355    version.  It *also* appears that some of the encodings may disagree
1356    with the specifications, but that's a separate problem.  */
1357 
1358 /**** asn1 macros ****/
1359 #if 0
1360    How to write an asn1 encoder function using these macros:
1361 
1362    asn1_error_code asn1_encode_krb5_substructure(asn1buf *buf,
1363                                                  const krb5_type *val,
1364                                                  int *retlen)
1365    {
1366      asn1_setup();
1367 
1368      asn1_addfield(val->last_field, n, asn1_type);
1369      asn1_addfield(rep->next_to_last_field, n-1, asn1_type);
1370      ...
1371 
1372      /* for OPTIONAL fields */
1373      if (rep->field_i == should_not_be_omitted)
1374        asn1_addfield(rep->field_i, i, asn1_type);
1375 
1376      /* for string fields (these encoders take an additional argument,
1377         the length of the string) */
1378      addlenfield(rep->field_length, rep->field, i-1, asn1_type);
1379 
1380      /* if you really have to do things yourself... */
1381      retval = asn1_encode_asn1_type(buf,rep->field,&length);
1382      if (retval) return retval;
1383      sum += length;
1384      retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, tag_number, length,
1385                              &length);
1386      if (retval) return retval;
1387      sum += length;
1388 
1389      ...
1390      asn1_addfield(rep->second_field, 1, asn1_type);
1391      asn1_addfield(rep->first_field, 0, asn1_type);
1392      asn1_makeseq();
1393 
1394      asn1_cleanup();
1395    }
1396 #endif
1397 
1398 /* asn1_addlenfield -- add a field whose length must be separately specified */
1399 #define asn1_addlenfield(len,value,tag,encoder)\
1400 { unsigned int length; \
1401   retval = encoder(buf,len,value,&length);      \
1402   if (retval) {\
1403     return retval; }\
1404   sum += length;\
1405   retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
1406   if (retval) {\
1407     return retval; }\
1408   sum += length; }
1409 
1410 /* asn1_addfield_implicit -- add an implicitly tagged field, or component, to the encoding */
1411 #define asn1_addfield_implicit(value,tag,encoder)\
1412 { unsigned int length;\
1413   retval = encoder(buf,value,&length);\
1414   if (retval) {\
1415     return retval; }\
1416   sum += length;\
1417   retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,length,&length); \
1418   if (retval) {\
1419     return retval; }\
1420   sum += length; }
1421 
1422 /* asn1_insert_implicit_octetstring -- add an octet string with implicit tagging */
1423 #define asn1_insert_implicit_octetstring(len,value,tag)\
1424 { unsigned int length;\
1425   retval = asn1buf_insert_octetstring(buf,len,value);\
1426   if (retval) {\
1427     return retval; }\
1428   sum += len;\
1429   retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,len,&length); \
1430   if (retval) {\
1431     return retval; }\
1432   sum += length; }
1433 
1434 /* asn1_insert_implicit_bitstring -- add a bitstring with implicit tagging */
1435 /* needs "length" declared in enclosing context */
1436 #define asn1_insert_implicit_bitstring(len,value,tag)\
1437 { retval = asn1buf_insert_octetstring(buf,len,value); \
1438   if (retval) {\
1439     return retval; }\
1440   sum += len;\
1441   retval = asn1buf_insert_octet(buf, 0);\
1442   if (retval) {\
1443     return retval; }\
1444   sum++;\
1445   retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,tag,len+1,&length); \
1446   if (retval) {\
1447     return retval; }\
1448   sum += length; }
1449 
1450 #ifndef DISABLE_PKINIT
1451 
1452 /* Callable encoders for the types defined above, until the PKINIT
1453    encoders get converted.  */
1454 MAKE_ENCFN(asn1_encode_realm, realm_of_principal_data);
1455 MAKE_ENCFN(asn1_encode_principal_name, principal_data);
1456 MAKE_ENCFN(asn1_encode_encryption_key, encryption_key);
1457 MAKE_ENCFN(asn1_encode_checksum, checksum);
1458 
1459 static asn1_error_code
1460 asn1_encode_kerberos_time(asn1buf *buf, const krb5_timestamp val,
1461                           unsigned int *retlen)
1462 {
1463     return asn1_encode_kerberos_time_at(buf,&val,retlen);
1464 }
1465 
1466 /* Now the real PKINIT encoder functions.  */
1467 asn1_error_code asn1_encode_pk_authenticator(asn1buf *buf, const krb5_pk_authenticator *val, unsigned int *retlen)
1468 {
1469     asn1_setup();
1470     asn1_addlenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_encode_octetstring);
1471     asn1_addfield(val->nonce, 2, asn1_encode_integer);
1472     asn1_addfield(val->ctime, 1, asn1_encode_kerberos_time);
1473     asn1_addfield(val->cusec, 0, asn1_encode_integer);
1474 
1475     asn1_makeseq();
1476     asn1_cleanup();
1477 }
1478 
1479 asn1_error_code asn1_encode_pk_authenticator_draft9(asn1buf *buf, const krb5_pk_authenticator_draft9 *val, unsigned int *retlen)
1480 {
1481     asn1_setup();
1482 
1483     asn1_addfield(val->nonce, 4, asn1_encode_integer);
1484     asn1_addfield(val->ctime, 3, asn1_encode_kerberos_time);
1485     asn1_addfield(val->cusec, 2, asn1_encode_integer);
1486     asn1_addfield(val->kdcName, 1, asn1_encode_realm);
1487     asn1_addfield(val->kdcName, 0, asn1_encode_principal_name);
1488 
1489     asn1_makeseq();
1490     asn1_cleanup();
1491 }
1492 
1493 
1494 asn1_error_code asn1_encode_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier *val, unsigned int *retlen)
1495 {
1496     asn1_setup();
1497 
1498     if (val->parameters.length != 0) {
1499         retval = asn1buf_insert_octetstring(buf, val->parameters.length,
1500                                             val->parameters.data);
1501         if (retval)
1502             return retval;
1503         sum += val->parameters.length;
1504     }
1505 
1506     {
1507         unsigned int length;
1508         retval = asn1_encode_oid(buf, val->algorithm.length,
1509                                  val->algorithm.data,
1510                                  &length);
1511 
1512         if (retval)
1513             return retval;
1514         sum += length;
1515     }
1516 
1517     asn1_makeseq();
1518     asn1_cleanup();
1519 }
1520 
1521 asn1_error_code asn1_encode_subject_pk_info(asn1buf *buf, const krb5_subject_pk_info *val, unsigned int *retlen)
1522 {
1523     asn1_setup();
1524 
1525     {
1526         unsigned int length;
1527         asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,ASN1_BITSTRING);
1528     }
1529 
1530     if (val->algorithm.parameters.length != 0) {
1531         unsigned int length;
1532 
1533         retval = asn1buf_insert_octetstring(buf, val->algorithm.parameters.length,
1534                                             val->algorithm.parameters.data);
1535         if (retval)
1536             return retval;
1537         sum += val->algorithm.parameters.length;
1538 
1539         retval = asn1_encode_oid(buf, val->algorithm.algorithm.length,
1540                                  val->algorithm.algorithm.data,
1541                                  &length);
1542 
1543         if (retval)
1544             return retval;
1545         sum += length;
1546 
1547 
1548         retval = asn1_make_etag(buf, UNIVERSAL, ASN1_SEQUENCE,
1549                                 val->algorithm.parameters.length + length,
1550                                 &length);
1551 
1552         if (retval)
1553             return retval;
1554         sum += length;
1555     }
1556 
1557     asn1_makeseq();
1558     asn1_cleanup();
1559 }
1560 
1561 asn1_error_code asn1_encode_sequence_of_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier **val, unsigned int *retlen)
1562 {
1563     asn1_setup();
1564     int i;
1565 
1566     if (val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
1567 
1568     for (i=0; val[i] != NULL; i++);
1569     for (i--; i>=0; i--) {
1570         unsigned int length;
1571         retval = asn1_encode_algorithm_identifier(buf,val[i],&length);
1572         if (retval) return retval;
1573         sum += length;
1574     }
1575     asn1_makeseq();
1576 
1577     asn1_cleanup();
1578 }
1579 
1580 asn1_error_code asn1_encode_auth_pack(asn1buf *buf, const krb5_auth_pack *val, unsigned int *retlen)
1581 {
1582     asn1_setup();
1583 
1584     if (val->clientDHNonce.length != 0)
1585         asn1_addlenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_encode_octetstring);
1586     if (val->supportedCMSTypes != NULL)
1587         asn1_addfield((const krb5_algorithm_identifier **)val->supportedCMSTypes,2,asn1_encode_sequence_of_algorithm_identifier);
1588     if (val->clientPublicValue != NULL)
1589         asn1_addfield(val->clientPublicValue,1,asn1_encode_subject_pk_info);
1590     asn1_addfield(&(val->pkAuthenticator),0,asn1_encode_pk_authenticator);
1591 
1592     asn1_makeseq();
1593     asn1_cleanup();
1594 }
1595 
1596 asn1_error_code asn1_encode_auth_pack_draft9(asn1buf *buf, const krb5_auth_pack_draft9 *val, unsigned int *retlen)
1597 {
1598     asn1_setup();
1599 
1600     if (val->clientPublicValue != NULL)
1601         asn1_addfield(val->clientPublicValue, 1, asn1_encode_subject_pk_info);
1602     asn1_addfield(&(val->pkAuthenticator), 0, asn1_encode_pk_authenticator_draft9);
1603 
1604     asn1_makeseq();
1605     asn1_cleanup();
1606 }
1607 
1608 asn1_error_code asn1_encode_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier *val, unsigned int *retlen)
1609 {
1610     asn1_setup();
1611 
1612     /* Verify there is something to encode */
1613     if (val->subjectKeyIdentifier.length == 0 && val->issuerAndSerialNumber.length == 0 && val->subjectName.length == 0)
1614         return ASN1_MISSING_FIELD;
1615 
1616     if (val->subjectKeyIdentifier.length != 0)
1617         asn1_insert_implicit_octetstring(val->subjectKeyIdentifier.length,val->subjectKeyIdentifier.data,2);
1618 
1619     if (val->issuerAndSerialNumber.length != 0)
1620         asn1_insert_implicit_octetstring(val->issuerAndSerialNumber.length,val->issuerAndSerialNumber.data,1);
1621 
1622     if (val->subjectName.length != 0)
1623         asn1_insert_implicit_octetstring(val->subjectName.length,val->subjectName.data,0);
1624 
1625     asn1_makeseq();
1626     asn1_cleanup();
1627 }
1628 
1629 asn1_error_code asn1_encode_sequence_of_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen)
1630 {
1631     asn1_setup();
1632     int i;
1633 
1634     if (val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
1635 
1636     for (i=0; val[i] != NULL; i++);
1637     for (i--; i>=0; i--) {
1638         unsigned int length;
1639         retval = asn1_encode_external_principal_identifier(buf,val[i],&length);
1640         if (retval) return retval;
1641         sum += length;
1642     }
1643     asn1_makeseq();
1644 
1645     asn1_cleanup();
1646 }
1647 
1648 asn1_error_code asn1_encode_pa_pk_as_req(asn1buf *buf, const krb5_pa_pk_as_req *val, unsigned int *retlen)
1649 {
1650     asn1_setup();
1651 
1652     if (val->kdcPkId.length != 0)
1653         asn1_insert_implicit_octetstring(val->kdcPkId.length,val->kdcPkId.data,2);
1654 
1655     if (val->trustedCertifiers != NULL)
1656         asn1_addfield((const krb5_external_principal_identifier **)val->trustedCertifiers,1,asn1_encode_sequence_of_external_principal_identifier);
1657 
1658     asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0);
1659 
1660     asn1_makeseq();
1661     asn1_cleanup();
1662 }
1663 
1664 asn1_error_code asn1_encode_trusted_ca(asn1buf *buf, const krb5_trusted_ca *val, unsigned int *retlen)
1665 {
1666     asn1_setup();
1667 
1668     switch (val->choice) {
1669     case choice_trusted_cas_issuerAndSerial:
1670         asn1_insert_implicit_octetstring(val->u.issuerAndSerial.length,val->u.issuerAndSerial.data,2);
1671         break;
1672     case choice_trusted_cas_caName:
1673         asn1_insert_implicit_octetstring(val->u.caName.length,val->u.caName.data,1);
1674         break;
1675     case choice_trusted_cas_principalName:
1676         asn1_addfield_implicit(val->u.principalName,0,asn1_encode_principal_name);
1677         break;
1678     default:
1679         return ASN1_MISSING_FIELD;
1680     }
1681 
1682     asn1_cleanup();
1683 }
1684 
1685 asn1_error_code asn1_encode_sequence_of_trusted_ca(asn1buf *buf, const krb5_trusted_ca **val, unsigned int *retlen)
1686 {
1687     asn1_setup();
1688     int i;
1689 
1690     if (val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
1691 
1692     for (i=0; val[i] != NULL; i++);
1693     for (i--; i>=0; i--) {
1694         unsigned int length;
1695         retval = asn1_encode_trusted_ca(buf,val[i],&length);
1696         if (retval) return retval;
1697         sum += length;
1698     }
1699     asn1_makeseq();
1700     asn1_cleanup();
1701 }
1702 
1703 asn1_error_code asn1_encode_pa_pk_as_req_draft9(asn1buf *buf, const krb5_pa_pk_as_req_draft9 *val, unsigned int *retlen)
1704 {
1705     asn1_setup();
1706 
1707     if (val->encryptionCert.length != 0)
1708         asn1_insert_implicit_octetstring(val->encryptionCert.length,val->encryptionCert.data,3);
1709 
1710     if (val->kdcCert.length != 0)
1711         asn1_insert_implicit_octetstring(val->kdcCert.length,val->kdcCert.data,2);
1712 
1713     if (val->trustedCertifiers != NULL)
1714         asn1_addfield((const krb5_trusted_ca **)val->trustedCertifiers,1,asn1_encode_sequence_of_trusted_ca);
1715 
1716     asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0);
1717 
1718     asn1_makeseq();
1719     asn1_cleanup();
1720 }
1721 
1722 asn1_error_code asn1_encode_dh_rep_info(asn1buf *buf, const krb5_dh_rep_info *val, unsigned int *retlen)
1723 {
1724     asn1_setup();
1725 
1726     if (val->serverDHNonce.length != 0)
1727         asn1_insert_implicit_octetstring(val->serverDHNonce.length,val->serverDHNonce.data,1);
1728 
1729     asn1_insert_implicit_octetstring(val->dhSignedData.length,val->dhSignedData.data,0);
1730 
1731     asn1_makeseq();
1732     asn1_cleanup();
1733 }
1734 
1735 asn1_error_code asn1_encode_kdc_dh_key_info(asn1buf *buf, const krb5_kdc_dh_key_info *val, unsigned int *retlen)
1736 {
1737     asn1_setup();
1738 
1739     if (val->dhKeyExpiration != 0)
1740         asn1_addfield(val->dhKeyExpiration, 2, asn1_encode_kerberos_time);
1741     asn1_addfield(val->nonce, 1, asn1_encode_integer);
1742 
1743     {
1744         unsigned int length;
1745 
1746         asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,3);
1747         retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0,
1748                                 val->subjectPublicKey.length + 1 + length,
1749                                 &length);
1750         if (retval)
1751             return retval;
1752         sum += length;
1753     }
1754 
1755     asn1_makeseq();
1756     asn1_cleanup();
1757 }
1758 
1759 asn1_error_code asn1_encode_reply_key_pack(asn1buf *buf, const krb5_reply_key_pack *val, unsigned int *retlen)
1760 {
1761     asn1_setup();
1762 
1763     asn1_addfield(&(val->asChecksum), 1, asn1_encode_checksum);
1764     asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key);
1765 
1766     asn1_makeseq();
1767     asn1_cleanup();
1768 }
1769 
1770 asn1_error_code asn1_encode_reply_key_pack_draft9(asn1buf *buf, const krb5_reply_key_pack_draft9 *val, unsigned int *retlen)
1771 {
1772     asn1_setup();
1773 
1774     asn1_addfield(val->nonce, 1, asn1_encode_integer);
1775     asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key);
1776 
1777     asn1_makeseq();
1778     asn1_cleanup();
1779 }
1780 
1781 asn1_error_code asn1_encode_pa_pk_as_rep(asn1buf *buf, const krb5_pa_pk_as_rep *val, unsigned int *retlen)
1782 {
1783     asn1_setup();
1784 
1785     switch (val->choice)
1786     {
1787     case choice_pa_pk_as_rep_dhInfo:
1788         asn1_addfield(&(val->u.dh_Info), choice_pa_pk_as_rep_dhInfo, asn1_encode_dh_rep_info);
1789         break;
1790     case choice_pa_pk_as_rep_encKeyPack:
1791         asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1);
1792         break;
1793     default:
1794         return ASN1_MISSING_FIELD;
1795     }
1796 
1797     asn1_cleanup();
1798 }
1799 
1800 asn1_error_code asn1_encode_pa_pk_as_rep_draft9(asn1buf *buf, const krb5_pa_pk_as_rep_draft9 *val, unsigned int *retlen)
1801 {
1802     asn1_setup();
1803 
1804     switch (val->choice)
1805     {
1806     case choice_pa_pk_as_rep_draft9_dhSignedData:
1807         asn1_insert_implicit_octetstring(val->u.dhSignedData.length,val->u.dhSignedData.data,0);
1808         break;
1809     case choice_pa_pk_as_rep_encKeyPack:
1810         asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1);
1811         break;
1812     default:
1813         return ASN1_MISSING_FIELD;
1814     }
1815 
1816     asn1_cleanup();
1817 }
1818 
1819 asn1_error_code asn1_encode_td_trusted_certifiers(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen)
1820 {
1821     asn1_setup();
1822     {
1823         unsigned int length;
1824         retval = asn1_encode_sequence_of_external_principal_identifier(buf, val, &length);
1825         if (retval)
1826             return retval;
1827         /* length set but ignored?  sum not updated?  */
1828     }
1829     asn1_cleanup();
1830 }
1831 
1832 #endif /* DISABLE_PKINIT */
1833 
1834 asn1_error_code asn1_encode_sequence_of_typed_data(asn1buf *buf, const krb5_typed_data **val, unsigned int *retlen)
1835 {
1836     asn1_setup();
1837     int i;
1838 
1839     if (val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
1840 
1841     for (i=0; val[i] != NULL; i++);
1842     for (i--; i>=0; i--) {
1843         unsigned int length;
1844 
1845         retval = asn1_encode_typed_data(buf,val[i],&length);
1846         if (retval) return retval;
1847         sum += length;
1848     }
1849     asn1_makeseq();
1850 
1851     asn1_cleanup();
1852 }
1853 
1854 asn1_error_code asn1_encode_typed_data(asn1buf *buf, const krb5_typed_data *val, unsigned int *retlen)
1855 {
1856     asn1_setup();
1857     asn1_addlenfield(val->length, val->data, 1, asn1_encode_octetstring);
1858     asn1_addfield(val->type, 0, asn1_encode_integer);
1859     asn1_makeseq();
1860     asn1_cleanup();
1861 }
1862