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