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