1 
2 /*
3  * src/lib/krb5/asn.1/krb5_encode.c
4  *
5  * Copyright 1994 by the Massachusetts Institute of Technology.
6  * All Rights Reserved.
7  *
8  * Export of this software from the United States of America may
9  *   require a specific license from the United States Government.
10  *   It is the responsibility of any person or organization contemplating
11  *   export to obtain such a license before exporting.
12  *
13  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
14  * distribute this software and its documentation for any purpose and
15  * without fee is hereby granted, provided that the above copyright
16  * notice appear in all copies and that both that copyright notice and
17  * this permission notice appear in supporting documentation, and that
18  * the name of M.I.T. not be used in advertising or publicity pertaining
19  * to distribution of the software without specific, written prior
20  * permission.  Furthermore if you modify this software you must label
21  * your software as modified software and not distribute it in such a
22  * fashion that it might be confused with the original M.I.T. software.
23  * M.I.T. makes no representations about the suitability of
24  * this software for any purpose.  It is provided "as is" without express
25  * or implied warranty.
26  */
27 
28 #include "k5-int.h"
29 #include "asn1_k_encode.h"
30 #include "asn1_encode.h"
31 #include "krbasn1.h"
32 #include "asn1buf.h"
33 #include "asn1_make.h"
34 
35 /**************** Macros (these save a lot of typing) ****************/
36 
37 /**** krb5 macros ****/
38 #if 0
39    How to write a krb5 encoder function using these macros:
40 
41    asn1_error_code encode_krb5_structure(const krb5_type *rep,
42                                          krb5_data **code)
43    {
44      krb5_setup();
45 
46      krb5_addfield(rep->last_field, n, asn1_type);
47      krb5_addfield(rep->next_to_last_field, n-1, asn1_type);
48      ...
49 
50      /* for OPTIONAL fields */
51      if(rep->field_i == should_not_be_omitted)
52        krb5_addfield(rep->field_i, i, asn1_type);
53 
54      /* for string fields (these encoders take an additional argument,
55 	the length of the string) */
56      addlenfield(rep->field_length, rep->field, i-1, asn1_type);
57 
58      /* if you really have to do things yourself... */
59      retval = asn1_encode_asn1_type(buf,rep->field,&length);
60      if(retval) return retval;
61      sum += length;
62      retval = asn1_make_etag(buf,
63 			    [UNIVERSAL/APPLICATION/CONTEXT_SPECIFIC/PRIVATE],
64 			    tag_number, length, &length);
65      if(retval) return retval;
66      sum += length;
67 
68      ...
69      krb5_addfield(rep->second_field, 1, asn1_type);
70      krb5_addfield(rep->first_field, 0, asn1_type);
71      krb5_makeseq();
72      krb5_apptag(tag_number);
73 
74      krb5_cleanup();
75    }
76 #endif
77 
78 /* setup() -- create and initialize bookkeeping variables
79      retval: stores error codes returned from subroutines
80      buf: the coding buffer
81      length: length of the most-recently produced encoding
82      sum: cumulative length of the entire encoding */
83 #define krb5_setup()\
84   asn1_error_code retval;\
85   asn1buf *buf=NULL;\
86   unsigned int length, sum=0;\
87 \
88   if(rep == NULL) return ASN1_MISSING_FIELD;\
89 \
90   retval = asn1buf_create(&buf);\
91   if(retval) return retval
92 
93 /* krb5_addfield -- add a field, or component, to the encoding */
94 #define krb5_addfield(value,tag,encoder)\
95 { retval = encoder(buf,value,&length);\
96   if(retval){\
97     asn1buf_destroy(&buf);\
98     return retval; }\
99   sum += length;\
100   retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
101   if(retval){\
102     asn1buf_destroy(&buf);\
103     return retval; }\
104   sum += length; }
105 
106 /* krb5_addlenfield -- add a field whose length must be separately specified */
107 #define krb5_addlenfield(len,value,tag,encoder)\
108 { retval = encoder(buf,len,value,&length);\
109   if(retval){\
110     asn1buf_destroy(&buf);\
111     return retval; }\
112   sum += length;\
113   retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
114   if(retval){\
115     asn1buf_destroy(&buf);\
116     return retval; }\
117   sum += length; }
118 
119 /* form a sequence (by adding a sequence header to the current encoding) */
120 #define krb5_makeseq()\
121   retval = asn1_make_sequence(buf,sum,&length);\
122   if(retval){\
123     asn1buf_destroy(&buf);\
124     return retval; }\
125   sum += length
126 
127 /* add an APPLICATION class tag to the current encoding */
128 #define krb5_apptag(num)\
129   retval = asn1_make_etag(buf,APPLICATION,num,sum,&length);\
130   if(retval){\
131     asn1buf_destroy(&buf);\
132     return retval; }\
133   sum += length
134 
135 /* produce the final output and clean up the workspace */
136 #define krb5_cleanup()\
137   retval = asn12krb5_buf(buf,code);\
138   if(retval){\
139     asn1buf_destroy(&buf);\
140     return retval; }\
141   retval = asn1buf_destroy(&buf);\
142   if(retval){\
143     return retval; }\
144 \
145   return 0
146 
147 krb5_error_code encode_krb5_authenticator(const krb5_authenticator *rep, krb5_data **code)
148 {
149   krb5_setup();
150 
151   /* authorization-data[8]	AuthorizationData OPTIONAL */
152   if(rep->authorization_data != NULL &&
153      rep->authorization_data[0] != NULL){
154     retval = asn1_encode_authorization_data(buf, (const krb5_authdata **)
155 					    rep->authorization_data,
156 					    &length);
157     if(retval){
158       asn1buf_destroy(&buf);
159       return retval; }
160     sum += length;
161     retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,8,length,&length);
162     if(retval){
163       asn1buf_destroy(&buf);
164       return retval; }
165     sum += length;
166   }
167 
168   /* seq-number[7]		INTEGER OPTIONAL */
169   if(rep->seq_number != 0)
170     krb5_addfield(rep->seq_number,7,asn1_encode_unsigned_integer);
171 
172   /* subkey[6]			EncryptionKey OPTIONAL */
173   if(rep->subkey != NULL)
174     krb5_addfield(rep->subkey,6,asn1_encode_encryption_key);
175 
176   /* ctime[5]			KerberosTime */
177   krb5_addfield(rep->ctime,5,asn1_encode_kerberos_time);
178 
179   /* cusec[4]			INTEGER */
180   krb5_addfield(rep->cusec,4,asn1_encode_integer);
181 
182   /* cksum[3]			Checksum OPTIONAL */
183   if(rep->checksum != NULL)
184     krb5_addfield(rep->checksum,3,asn1_encode_checksum);
185 
186   /* cname[2]			PrincipalName */
187   krb5_addfield(rep->client,2,asn1_encode_principal_name);
188 
189   /* crealm[1]			Realm */
190   krb5_addfield(rep->client,1,asn1_encode_realm);
191 
192   /* authenticator-vno[0]	INTEGER */
193   krb5_addfield(KVNO,0,asn1_encode_integer);
194 
195   /* Authenticator ::= [APPLICATION 2] SEQUENCE */
196   krb5_makeseq();
197   krb5_apptag(2);
198 
199   krb5_cleanup();
200 }
201 
202 krb5_error_code encode_krb5_ticket(const krb5_ticket *rep, krb5_data **code)
203 {
204   krb5_setup();
205 
206   /* enc-part[3]	EncryptedData */
207   krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
208 
209   /* sname [2]		PrincipalName */
210   krb5_addfield(rep->server,2,asn1_encode_principal_name);
211 
212   /* realm [1]		Realm */
213   krb5_addfield(rep->server,1,asn1_encode_realm);
214 
215   /* tkt-vno [0]	INTEGER */
216   krb5_addfield(KVNO,0,asn1_encode_integer);
217 
218   /* Ticket ::= [APPLICATION 1] SEQUENCE */
219   krb5_makeseq();
220   krb5_apptag(1);
221 
222   krb5_cleanup();
223 }
224 
225 krb5_error_code encode_krb5_encryption_key(const krb5_keyblock *rep, krb5_data **code)
226 {
227   krb5_setup();
228 
229   /* keyvalue[1]	OCTET STRING */
230   krb5_addlenfield(rep->length,rep->contents,1,asn1_encode_octetstring);
231 
232   /* enctype[0]		INTEGER */
233   krb5_addfield(rep->enctype,0,asn1_encode_integer);
234 
235   /* EncryptionKey ::= SEQUENCE */
236   krb5_makeseq();
237 
238   krb5_cleanup();
239 }
240 
241 krb5_error_code encode_krb5_enc_tkt_part(const krb5_enc_tkt_part *rep, krb5_data **code)
242 {
243   krb5_setup();
244 
245   /* authorization-data[10]	AuthorizationData OPTIONAL */
246   if(rep->authorization_data != NULL &&
247      rep->authorization_data[0] != NULL)
248     krb5_addfield((const krb5_authdata**)rep->authorization_data,
249 		  10,asn1_encode_authorization_data);
250 
251   /* caddr[9]			HostAddresses OPTIONAL */
252   if(rep->caddrs != NULL && rep->caddrs[0] != NULL)
253     krb5_addfield((const krb5_address**)rep->caddrs,9,asn1_encode_host_addresses);
254 
255   /* renew-till[8]		KerberosTime OPTIONAL */
256   if(rep->times.renew_till)
257     krb5_addfield(rep->times.renew_till,8,asn1_encode_kerberos_time);
258 
259   /* endtime[7]			KerberosTime */
260   krb5_addfield(rep->times.endtime,7,asn1_encode_kerberos_time);
261 
262   /* starttime[6]		KerberosTime OPTIONAL */
263   if(rep->times.starttime)
264     krb5_addfield(rep->times.starttime,6,asn1_encode_kerberos_time);
265 
266   /* authtime[5]		KerberosTime */
267   krb5_addfield(rep->times.authtime,5,asn1_encode_kerberos_time);
268 
269   /* transited[4]		TransitedEncoding */
270   krb5_addfield(&(rep->transited),4,asn1_encode_transited_encoding);
271 
272   /* cname[3]			PrincipalName */
273   krb5_addfield(rep->client,3,asn1_encode_principal_name);
274 
275   /* crealm[2]			Realm */
276   krb5_addfield(rep->client,2,asn1_encode_realm);
277 
278   /* key[1]			EncryptionKey */
279   krb5_addfield(rep->session,1,asn1_encode_encryption_key);
280 
281   /* flags[0]			TicketFlags */
282   krb5_addfield(rep->flags,0,asn1_encode_ticket_flags);
283 
284   /* EncTicketPart ::= [APPLICATION 3] SEQUENCE */
285   krb5_makeseq();
286   krb5_apptag(3);
287 
288   krb5_cleanup();
289 }
290 
291 krb5_error_code encode_krb5_enc_kdc_rep_part(const krb5_enc_kdc_rep_part *rep, krb5_data **code)
292 {
293   asn1_error_code retval;
294   asn1buf *buf=NULL;
295   unsigned int length, sum=0;
296 
297   if(rep == NULL) return ASN1_MISSING_FIELD;
298 
299   retval = asn1buf_create(&buf);
300   if(retval) return retval;
301 
302   retval = asn1_encode_enc_kdc_rep_part(buf,rep,&length);
303   if(retval) return retval;
304   sum += length;
305 
306 #ifdef KRB5_ENCKRB5KDCREPPART_COMPAT
307   krb5_apptag(26);
308 #else
309   /* XXX WRONG!!! Should use 25 || 26, not the outer KDC_REP tags! */
310   if (rep->msg_type == KRB5_AS_REP) { krb5_apptag(ASN1_KRB_AS_REP); }
311   else if (rep->msg_type == KRB5_TGS_REP) { krb5_apptag(ASN1_KRB_TGS_REP); }
312   else return KRB5_BADMSGTYPE;
313 #endif
314   krb5_cleanup();
315 }
316 
317 /* yes, the translation is identical to that used for KDC__REP */
318 krb5_error_code encode_krb5_as_rep(const krb5_kdc_rep *rep, krb5_data **code)
319 {
320   krb5_setup();
321 
322   /* AS-REP ::= [APPLICATION 11] KDC-REP */
323   retval = asn1_encode_kdc_rep(KRB5_AS_REP,buf,rep,&length);
324   if(retval) return retval;
325   sum += length;
326 
327   krb5_apptag(11);
328 
329   krb5_cleanup();
330 }
331 
332 /* yes, the translation is identical to that used for KDC__REP */
333 krb5_error_code encode_krb5_tgs_rep(const krb5_kdc_rep *rep, krb5_data **code)
334 {
335   krb5_setup();
336 
337   /* TGS-REP ::= [APPLICATION 13] KDC-REP */
338   retval = asn1_encode_kdc_rep(KRB5_TGS_REP,buf,rep,&length);
339   if(retval) return retval;
340   sum += length;
341 
342   krb5_apptag(13);
343 
344   krb5_cleanup();
345 }
346 
347 krb5_error_code encode_krb5_ap_req(const krb5_ap_req *rep, krb5_data **code)
348 {
349   krb5_setup();
350 
351   /* authenticator[4]	EncryptedData */
352   krb5_addfield(&(rep->authenticator),4,asn1_encode_encrypted_data);
353 
354   /* ticket[3]		Ticket */
355   krb5_addfield(rep->ticket,3,asn1_encode_ticket);
356 
357   /* ap-options[2]	APOptions */
358   krb5_addfield(rep->ap_options,2,asn1_encode_ap_options);
359 
360   /* msg-type[1]	INTEGER */
361   krb5_addfield(ASN1_KRB_AP_REQ,1,asn1_encode_integer);
362 
363   /* pvno[0]		INTEGER */
364   krb5_addfield(KVNO,0,asn1_encode_integer);
365 
366   /* AP-REQ ::=	[APPLICATION 14] SEQUENCE */
367   krb5_makeseq();
368   krb5_apptag(14);
369 
370   krb5_cleanup();
371 }
372 
373 krb5_error_code encode_krb5_ap_rep(const krb5_ap_rep *rep, krb5_data **code)
374 {
375   krb5_setup();
376 
377   /* enc-part[2]	EncryptedData */
378   krb5_addfield(&(rep->enc_part),2,asn1_encode_encrypted_data);
379 
380   /* msg-type[1]	INTEGER */
381   krb5_addfield(ASN1_KRB_AP_REP,1,asn1_encode_integer);
382 
383   /* pvno[0]		INTEGER */
384   krb5_addfield(KVNO,0,asn1_encode_integer);
385 
386   /* AP-REP ::=	[APPLICATION 15] SEQUENCE */
387   krb5_makeseq();
388   krb5_apptag(15);
389 
390   krb5_cleanup();
391 }
392 
393 
394 krb5_error_code encode_krb5_ap_rep_enc_part(const krb5_ap_rep_enc_part *rep, krb5_data **code)
395 {
396   krb5_setup();
397 
398   /* seq-number[3]	INTEGER OPTIONAL */
399   if(rep->seq_number)
400     krb5_addfield(rep->seq_number,3,asn1_encode_unsigned_integer);
401 
402   /* subkey[2]		EncryptionKey OPTIONAL */
403   if(rep->subkey != NULL)
404     krb5_addfield(rep->subkey,2,asn1_encode_encryption_key);
405 
406   /* cusec[1]		INTEGER */
407   krb5_addfield(rep->cusec,1,asn1_encode_integer);
408 
409   /* ctime[0]		KerberosTime */
410   krb5_addfield(rep->ctime,0,asn1_encode_kerberos_time);
411 
412   /* EncAPRepPart ::= [APPLICATION 27] SEQUENCE */
413   krb5_makeseq();
414   krb5_apptag(27);
415 
416   krb5_cleanup();
417 }
418 
419 krb5_error_code encode_krb5_as_req(const krb5_kdc_req *rep, krb5_data **code)
420 {
421   krb5_setup();
422 
423   /* AS-REQ ::= [APPLICATION 10] KDC-REQ */
424   retval = asn1_encode_kdc_req(KRB5_AS_REQ,buf,rep,&length);
425   if(retval) return retval;
426   sum += length;
427 
428   krb5_apptag(10);
429 
430   krb5_cleanup();
431 }
432 
433 krb5_error_code encode_krb5_tgs_req(const krb5_kdc_req *rep, krb5_data **code)
434 {
435   krb5_setup();
436 
437   /* TGS-REQ ::= [APPLICATION 12] KDC-REQ */
438   retval = asn1_encode_kdc_req(KRB5_TGS_REQ,buf,rep,&length);
439   if(retval) return retval;
440   sum += length;
441 
442   krb5_apptag(12);
443 
444   krb5_cleanup();
445 }
446 
447 krb5_error_code encode_krb5_kdc_req_body(const krb5_kdc_req *rep, krb5_data **code)
448 {
449   krb5_setup();
450 
451   retval = asn1_encode_kdc_req_body(buf,rep,&length);
452   if(retval) return retval;
453   sum += length;
454 
455   krb5_cleanup();
456 }
457 
458 
459 krb5_error_code encode_krb5_safe(const krb5_safe *rep, krb5_data **code)
460 {
461   krb5_setup();
462 
463   /* cksum[3]		Checksum */
464   krb5_addfield(rep->checksum,3,asn1_encode_checksum);
465 
466   /* safe-body[2]	KRB-SAFE-BODY */
467   krb5_addfield(rep,2,asn1_encode_krb_safe_body);
468 
469   /* msg-type[1]	INTEGER */
470   krb5_addfield(ASN1_KRB_SAFE,1,asn1_encode_integer);
471 
472   /* pvno[0]		INTEGER */
473   krb5_addfield(KVNO,0,asn1_encode_integer);
474 
475   /* KRB-SAFE ::= [APPLICATION 20] SEQUENCE */
476   krb5_makeseq();
477   krb5_apptag(20);
478 
479   krb5_cleanup();
480 }
481 
482 /*
483  * encode_krb5_safe_with_body
484  *
485  * Like encode_krb5_safe(), except takes a saved KRB-SAFE-BODY
486  * encoding to avoid problems with re-encoding.
487  */
488 krb5_error_code encode_krb5_safe_with_body(
489   const krb5_safe *rep,
490   const krb5_data *body,
491   krb5_data **code)
492 {
493   krb5_setup();
494 
495   if (body == NULL) {
496       asn1buf_destroy(&buf);
497       return ASN1_MISSING_FIELD;
498   }
499 
500   /* cksum[3]		Checksum */
501   krb5_addfield(rep->checksum,3,asn1_encode_checksum);
502 
503   /* safe-body[2]	KRB-SAFE-BODY */
504   krb5_addfield(body,2,asn1_encode_krb_saved_safe_body);
505 
506   /* msg-type[1]	INTEGER */
507   krb5_addfield(ASN1_KRB_SAFE,1,asn1_encode_integer);
508 
509   /* pvno[0]		INTEGER */
510   krb5_addfield(KVNO,0,asn1_encode_integer);
511 
512   /* KRB-SAFE ::= [APPLICATION 20] SEQUENCE */
513   krb5_makeseq();
514   krb5_apptag(20);
515 
516   krb5_cleanup();
517 }
518 
519 krb5_error_code encode_krb5_priv(const krb5_priv *rep, krb5_data **code)
520 {
521   krb5_setup();
522 
523   /* enc-part[3]	EncryptedData */
524   krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
525 
526   /* msg-type[1]	INTEGER */
527   krb5_addfield(ASN1_KRB_PRIV,1,asn1_encode_integer);
528 
529   /* pvno[0]		INTEGER */
530   krb5_addfield(KVNO,0,asn1_encode_integer);
531 
532   /* KRB-PRIV ::= [APPLICATION 21] SEQUENCE */
533   krb5_makeseq();
534   krb5_apptag(21);
535 
536   krb5_cleanup();
537 }
538 
539 krb5_error_code encode_krb5_enc_priv_part(const krb5_priv_enc_part *rep, krb5_data **code)
540 {
541   krb5_setup();
542 
543   /* r-address[5]	HostAddress OPTIONAL -- recip's addr */
544   if(rep->r_address)
545     krb5_addfield(rep->r_address,5,asn1_encode_host_address);
546 
547   /* s-address[4]	HostAddress -- sender's addr */
548   krb5_addfield(rep->s_address,4,asn1_encode_host_address);
549 
550   /* seq-number[3]	INTEGER OPTIONAL */
551   if(rep->seq_number)
552     krb5_addfield(rep->seq_number,3,asn1_encode_unsigned_integer);
553 
554   /* usec[2]		INTEGER OPTIONAL */
555   if(rep->timestamp){
556     krb5_addfield(rep->usec,2,asn1_encode_integer);
557     /* timestamp[1]	KerberosTime OPTIONAL */
558     krb5_addfield(rep->timestamp,1,asn1_encode_kerberos_time);
559   }
560 
561   /* user-data[0]	OCTET STRING */
562   krb5_addlenfield(rep->user_data.length,rep->user_data.data,0,asn1_encode_charstring);
563 
564   /* EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE */
565   krb5_makeseq();
566   krb5_apptag(28);
567 
568   krb5_cleanup();
569 }
570 
571 krb5_error_code encode_krb5_cred(const krb5_cred *rep, krb5_data **code)
572 {
573   krb5_setup();
574 
575   /* enc-part[3]	EncryptedData */
576   krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
577 
578   /* tickets[2]		SEQUENCE OF Ticket */
579   krb5_addfield((const krb5_ticket**)rep->tickets,2,asn1_encode_sequence_of_ticket);
580 
581   /* msg-type[1]	INTEGER, -- KRB_CRED */
582   krb5_addfield(ASN1_KRB_CRED,1,asn1_encode_integer);
583 
584   /* pvno[0]		INTEGER */
585   krb5_addfield(KVNO,0,asn1_encode_integer);
586 
587   /* KRB-CRED ::= [APPLICATION 22] SEQUENCE */
588   krb5_makeseq();
589   krb5_apptag(22);
590 
591   krb5_cleanup();
592 }
593 
594 krb5_error_code encode_krb5_enc_cred_part(const krb5_cred_enc_part *rep, krb5_data **code)
595 {
596   krb5_setup();
597 
598   /* r-address[5]	HostAddress OPTIONAL */
599   if(rep->r_address != NULL)
600     krb5_addfield(rep->r_address,5,asn1_encode_host_address);
601 
602   /* s-address[4]	HostAddress OPTIONAL */
603   if(rep->s_address != NULL)
604     krb5_addfield(rep->s_address,4,asn1_encode_host_address);
605 
606   /* usec[3]		INTEGER OPTIONAL */
607   if(rep->timestamp){
608     krb5_addfield(rep->usec,3,asn1_encode_integer);
609     /* timestamp[2]	KerberosTime OPTIONAL */
610     krb5_addfield(rep->timestamp,2,asn1_encode_kerberos_time);
611   }
612 
613   /* nonce[1]		INTEGER OPTIONAL */
614   if(rep->nonce)
615     krb5_addfield(rep->nonce,1,asn1_encode_integer);
616 
617   /* ticket-info[0]	SEQUENCE OF KrbCredInfo */
618   krb5_addfield((const krb5_cred_info**)rep->ticket_info,
619 		0,asn1_encode_sequence_of_krb_cred_info);
620 
621   /* EncKrbCredPart ::= [APPLICATION 29] SEQUENCE */
622   krb5_makeseq();
623   krb5_apptag(29);
624 
625   krb5_cleanup();
626 }
627 
628 krb5_error_code encode_krb5_error(const krb5_error *rep, krb5_data **code)
629 {
630   krb5_setup();
631 
632   /* e-data[12]		OCTET STRING OPTIONAL */
633   if(rep->e_data.data != NULL && rep->e_data.length > 0)
634     krb5_addlenfield(rep->e_data.length,rep->e_data.data,12,asn1_encode_charstring);
635 
636   /* e-text[11]		GeneralString OPTIONAL */
637   if(rep->text.data != NULL && rep->text.length > 0)
638     krb5_addlenfield(rep->text.length,rep->text.data,11,asn1_encode_generalstring);
639 
640   /* sname[10]		PrincipalName -- Correct name */
641   krb5_addfield(rep->server,10,asn1_encode_principal_name);
642 
643   /* realm[9]		Realm -- Correct realm */
644   krb5_addfield(rep->server,9,asn1_encode_realm);
645 
646   /* cname[8]		PrincipalName OPTIONAL */
647   if(rep->client != NULL){
648     krb5_addfield(rep->client,8,asn1_encode_principal_name);
649     /* crealm[7]		Realm OPTIONAL */
650     krb5_addfield(rep->client,7,asn1_encode_realm);
651   }
652 
653   /* error-code[6]	INTEGER */
654   krb5_addfield(rep->error,6,asn1_encode_ui_4);
655 
656   /* susec[5]		INTEGER */
657   krb5_addfield(rep->susec,5,asn1_encode_integer);
658 
659   /* stime[4]		KerberosTime */
660   krb5_addfield(rep->stime,4,asn1_encode_kerberos_time);
661 
662   /* cusec[3]		INTEGER OPTIONAL */
663   if(rep->cusec)
664     krb5_addfield(rep->cusec,3,asn1_encode_integer);
665 
666   /* ctime[2]		KerberosTime OPTIONAL */
667   if(rep->ctime)
668     krb5_addfield(rep->ctime,2,asn1_encode_kerberos_time);
669 
670   /* msg-type[1]	INTEGER */
671   krb5_addfield(ASN1_KRB_ERROR,1,asn1_encode_integer);
672 
673   /* pvno[0]		INTEGER */
674   krb5_addfield(KVNO,0,asn1_encode_integer);
675 
676   /* KRB-ERROR ::= [APPLICATION 30] SEQUENCE */
677   krb5_makeseq();
678   krb5_apptag(30);
679 
680   krb5_cleanup();
681 }
682 
683 krb5_error_code encode_krb5_authdata(const krb5_authdata **rep, krb5_data **code)
684 {
685   asn1_error_code retval;
686   asn1buf *buf=NULL;
687   unsigned int length;
688 
689   if(rep == NULL) return ASN1_MISSING_FIELD;
690 
691   retval = asn1buf_create(&buf);
692   if(retval) return retval;
693 
694   retval = asn1_encode_authorization_data(buf,(const krb5_authdata**)rep,
695 					  &length);
696   if(retval) return retval;
697 
698   krb5_cleanup();
699 }
700 
701 krb5_error_code encode_krb5_authdata_elt(const krb5_authdata *rep, krb5_data **code)
702 {
703   asn1_error_code retval;
704   asn1buf *buf=NULL;
705   unsigned int length;
706 
707   if(rep == NULL) return ASN1_MISSING_FIELD;
708 
709   retval = asn1buf_create(&buf);
710   if(retval) return retval;
711 
712   retval = asn1_encode_krb5_authdata_elt(buf,rep, &length);
713   if(retval) return retval;
714 
715   krb5_cleanup();
716 }
717 
718 krb5_error_code encode_krb5_alt_method(const krb5_alt_method *rep, krb5_data **code)
719 {
720   krb5_setup();
721 
722   /* method-data[1]		OctetString OPTIONAL */
723   if(rep->data != NULL && rep->length > 0)
724     krb5_addlenfield(rep->length,rep->data,1,asn1_encode_octetstring);
725 
726   /* method-type[0]		Integer */
727   krb5_addfield(rep->method,0,asn1_encode_integer);
728 
729   krb5_makeseq();
730 
731   krb5_cleanup();
732 }
733 
734 krb5_error_code encode_krb5_etype_info(const krb5_etype_info_entry **rep, krb5_data **code)
735 {
736   krb5_setup();
737   retval = asn1_encode_etype_info(buf,rep,&length, 0);
738   if(retval) return retval;
739   sum += length;
740   krb5_cleanup();
741 }
742 
743 krb5_error_code encode_krb5_etype_info2(const krb5_etype_info_entry **rep, krb5_data **code)
744 {
745   krb5_setup();
746   retval = asn1_encode_etype_info(buf,rep,&length, 1);
747   if(retval) return retval;
748   sum += length;
749   krb5_cleanup();
750 }
751 
752 
753 krb5_error_code encode_krb5_enc_data(const krb5_enc_data *rep, krb5_data **code)
754 {
755   krb5_setup();
756 
757   retval = asn1_encode_encrypted_data(buf,rep,&length);
758   if(retval) return retval;
759   sum += length;
760 
761   krb5_cleanup();
762 }
763 
764 krb5_error_code encode_krb5_pa_enc_ts(const krb5_pa_enc_ts *rep, krb5_data **code)
765 {
766   krb5_setup();
767 
768   /* pausec[1]                    INTEGER OPTIONAL */
769   if (rep->pausec)
770 	  krb5_addfield(rep->pausec,1,asn1_encode_integer);
771 
772   /* patimestamp[0]               KerberosTime, -- client's time */
773   krb5_addfield(rep->patimestamp,0,asn1_encode_kerberos_time);
774 
775   krb5_makeseq();
776 
777   krb5_cleanup();
778 }
779 
780 /* Sandia Additions */
781 krb5_error_code encode_krb5_pwd_sequence(const passwd_phrase_element *rep, krb5_data **code)
782 {
783   krb5_setup();
784   retval = asn1_encode_passwdsequence(buf,rep,&length);
785   if(retval) return retval;
786   sum += length;
787   krb5_cleanup();
788 }
789 
790 krb5_error_code encode_krb5_pwd_data(const krb5_pwd_data *rep, krb5_data **code)
791 {
792   krb5_setup();
793   krb5_addfield((const passwd_phrase_element**)rep->element,1,asn1_encode_sequence_of_passwdsequence);
794   krb5_addfield(rep->sequence_count,0,asn1_encode_integer);
795   krb5_makeseq();
796   krb5_cleanup();
797 }
798 
799 krb5_error_code encode_krb5_padata_sequence(const krb5_pa_data **rep, krb5_data **code)
800 {
801   krb5_setup();
802 
803   retval = asn1_encode_sequence_of_pa_data(buf,rep,&length);
804   if(retval) return retval;
805   sum += length;
806 
807   krb5_cleanup();
808 }
809 
810 /* sam preauth additions */
811 krb5_error_code encode_krb5_sam_challenge(const krb5_sam_challenge *rep, krb5_data **code)
812 {
813   krb5_setup();
814   retval = asn1_encode_sam_challenge(buf,rep,&length);
815   if(retval) return retval;
816   sum += length;
817   krb5_cleanup();
818 }
819 
820 krb5_error_code encode_krb5_sam_challenge_2(const krb5_sam_challenge_2 *rep, krb5_data **code)
821 {
822   krb5_setup();
823   retval = asn1_encode_sam_challenge_2(buf,rep,&length);
824   if(retval) return retval;
825   sum += length;
826   krb5_cleanup();
827 }
828 
829 krb5_error_code encode_krb5_sam_challenge_2_body(const krb5_sam_challenge_2_body *rep, krb5_data **code)
830 {
831   krb5_setup();
832   retval = asn1_encode_sam_challenge_2_body(buf,rep,&length);
833   if(retval) return retval;
834   sum += length;
835   krb5_cleanup();
836 }
837 
838 krb5_error_code encode_krb5_sam_key(const krb5_sam_key *rep, krb5_data **code)
839 {
840   krb5_setup();
841   retval = asn1_encode_sam_key(buf,rep,&length);
842   if(retval) return retval;
843   sum += length;
844   krb5_cleanup();
845 }
846 
847 krb5_error_code encode_krb5_enc_sam_response_enc(const krb5_enc_sam_response_enc *rep, krb5_data **code)
848 {
849   krb5_setup();
850   retval = asn1_encode_enc_sam_response_enc(buf,rep,&length);
851   if(retval) return retval;
852   sum += length;
853   krb5_cleanup();
854 }
855 
856 krb5_error_code encode_krb5_enc_sam_response_enc_2(const krb5_enc_sam_response_enc_2 *rep, krb5_data **code)
857 {
858   krb5_setup();
859   retval = asn1_encode_enc_sam_response_enc_2(buf,rep,&length);
860   if(retval) return retval;
861   sum += length;
862   krb5_cleanup();
863 }
864 
865 krb5_error_code encode_krb5_sam_response(const krb5_sam_response *rep, krb5_data **code)
866 {
867   krb5_setup();
868   retval = asn1_encode_sam_response(buf,rep,&length);
869   if(retval) return retval;
870   sum += length;
871   krb5_cleanup();
872 }
873 
874 krb5_error_code encode_krb5_sam_response_2(const krb5_sam_response_2 *rep, krb5_data **code)
875 {
876   krb5_setup();
877   retval = asn1_encode_sam_response_2(buf,rep,&length);
878   if(retval) return retval;
879   sum += length;
880   krb5_cleanup();
881 }
882 
883 krb5_error_code encode_krb5_predicted_sam_response(const krb5_predicted_sam_response *rep, krb5_data **code)
884 {
885   krb5_setup();
886   retval = asn1_encode_predicted_sam_response(buf,rep,&length);
887   if(retval) return retval;
888   sum += length;
889   krb5_cleanup();
890 }
891 
892 krb5_error_code encode_krb5_setpw_req(const krb5_principal target,
893 				      char *password, krb5_data **code)
894 {
895   /* Macros really want us to have a variable called rep which we do not need*/
896   const char *rep = "dummy string";
897 
898   krb5_setup();
899 
900   krb5_addfield(target,2,asn1_encode_realm);
901   krb5_addfield(target,1,asn1_encode_principal_name);
902   /* Solaris Kerberos */
903   krb5_addlenfield(strlen(password), (const unsigned char *)password,0,asn1_encode_octetstring);
904   krb5_makeseq();
905 
906 
907   krb5_cleanup();
908 }
909 
910 krb5_error_code encode_krb5_pa_pk_as_req(const krb5_pa_pk_as_req *rep, krb5_data **code)
911 {
912   krb5_setup();
913   retval = asn1_encode_pa_pk_as_req(buf,rep,&length);
914   if(retval) return retval;
915   sum += length;
916   krb5_cleanup();
917 }
918 
919 krb5_error_code encode_krb5_pa_pk_as_req_draft9(const krb5_pa_pk_as_req_draft9 *rep, krb5_data **code)
920 {
921   krb5_setup();
922   retval = asn1_encode_pa_pk_as_req_draft9(buf,rep,&length);
923   if(retval) return retval;
924   sum += length;
925   krb5_cleanup();
926 }
927 
928 krb5_error_code encode_krb5_pa_pk_as_rep(const krb5_pa_pk_as_rep *rep, krb5_data **code)
929 {
930   krb5_setup();
931   retval = asn1_encode_pa_pk_as_rep(buf,rep,&length);
932   if(retval) return retval;
933   sum += length;
934   krb5_cleanup();
935 }
936 
937 krb5_error_code encode_krb5_pa_pk_as_rep_draft9(const krb5_pa_pk_as_rep_draft9 *rep, krb5_data **code)
938 {
939   krb5_setup();
940   retval = asn1_encode_pa_pk_as_rep_draft9(buf,rep,&length);
941   if(retval) return retval;
942   sum += length;
943   krb5_cleanup();
944 }
945 
946 krb5_error_code encode_krb5_auth_pack(const krb5_auth_pack *rep, krb5_data **code)
947 {
948   krb5_setup();
949   retval = asn1_encode_auth_pack(buf,rep,&length);
950   if(retval) return retval;
951   sum += length;
952   krb5_cleanup();
953 }
954 
955 krb5_error_code encode_krb5_auth_pack_draft9(const krb5_auth_pack_draft9 *rep, krb5_data **code)
956 {
957   krb5_setup();
958   retval = asn1_encode_auth_pack_draft9(buf,rep,&length);
959   if(retval) return retval;
960   sum += length;
961   krb5_cleanup();
962 }
963 
964 krb5_error_code encode_krb5_kdc_dh_key_info(const krb5_kdc_dh_key_info *rep, krb5_data **code)
965 {
966   krb5_setup();
967   retval = asn1_encode_kdc_dh_key_info(buf,rep,&length);
968   if(retval) return retval;
969   sum += length;
970   krb5_cleanup();
971 }
972 
973 krb5_error_code encode_krb5_reply_key_pack(const krb5_reply_key_pack *rep, krb5_data **code)
974 {
975   krb5_setup();
976   retval = asn1_encode_reply_key_pack(buf,rep,&length);
977   if(retval) return retval;
978   sum += length;
979   krb5_cleanup();
980 }
981 
982 krb5_error_code encode_krb5_reply_key_pack_draft9(const krb5_reply_key_pack_draft9 *rep, krb5_data **code)
983 {
984   krb5_setup();
985   retval = asn1_encode_reply_key_pack_draft9(buf,rep,&length);
986   if(retval) return retval;
987   sum += length;
988   krb5_cleanup();
989 }
990 
991 krb5_error_code encode_krb5_td_trusted_certifiers(const krb5_external_principal_identifier **rep, krb5_data **code)
992 {
993   krb5_setup();
994   retval = asn1_encode_td_trusted_certifiers(buf,rep,&length);
995   if(retval) return retval;
996   sum += length;
997   krb5_cleanup();
998 }
999 
1000 krb5_error_code encode_krb5_typed_data(const krb5_typed_data **rep, krb5_data **code)
1001 {
1002   krb5_setup();
1003   retval = asn1_encode_sequence_of_typed_data(buf,rep,&length);
1004   if(retval) return retval;
1005   sum += length;
1006   krb5_cleanup();
1007 }
1008 
1009 krb5_error_code encode_krb5_td_dh_parameters(const krb5_algorithm_identifier **rep, krb5_data **code)
1010 {
1011   krb5_setup();
1012   retval = asn1_encode_sequence_of_algorithm_identifier(buf,rep,&length);
1013   if(retval) return retval;
1014   sum += length;
1015   krb5_cleanup();
1016 }
1017